Esbuild Plugin

WARNING

The esbuild feature in the current document is no longer maintained, we recommend using the Rspack + SWC solution, because Rspack + SWC provide better build performance, richer features, and better compatibility.

Please refer to 「Use Rspack」 for more information.

esbuild is a front-end build tool based on Golang. It has the functions of bundling, compiling and minimizing JavaScript code. Compared with traditional tools, the performance is significantly improved. When minimizing code, compared to webpack's built-in terser minimizer, esbuild has dozens of times better performance.

Modern.js Builder provides esbuild plugin that allow you to use esbuild instead of babel-loader, ts-loader and terser for transformation and minification process. When you enable esbuild in a large project, it can greatly reduce the time required for code compilation and compression, while effectively avoiding OOM (heap out of memory) problems.

Quick Start

Used in Modern.js framework

The Modern.js framework integrates the Builder's esbuild plugin by default, so you don't need to manually install and register the plugin, just use the tools.esbuild configuration:

export default defineConfig({
  tools: {
    esbuild: {
      loader: {
        target: 'chrome61',
      },
      minimize: {
        target: 'chrome61',
      },
    },
  },
});

Use via the Node API

If you use the Builder's Node API, you need to manually install and register the esbuild plugin.

Install

You can install the plugin with the following command:

npm
yarn
pnpm
bun
npm add @modern-js/builder-plugin-esbuild -D

Register

Register esbuild plugin through the addPlugins method:

import { builderPluginEsbuild } from '@modern-js/builder-plugin-esbuild';

// add the plugin to the builder instance
builder.addPlugins([builderPluginEsbuild()]);

Config

The plugin will enable code transformation and minification by default. You can also customize the behavior of the plugin through configuration.

loader

  • Type:
type LoaderOptions = EsbuildLoaderOptions | false | undefined;
  • Default:
const defaultOptions = {
  target: 'es2015',
  charset: builderConfig.output.charset,
};

This config is used to enable JavaScript/TypeScript transformation, which will replace babel-loader and ts-loader with esbuild-loader.

If you want to modify the options, you can check the esbuild-loader documentation.

Set JSX Format

When using esbuild for transformation, esbuild will read the compilerOptions.jsx field in tsconfig.json to determine which JSX syntax to use.

Therefore, you need to set the correct JSX syntax in tsconfig.json.

For example, React projects need to set compilerOptions.jsx to react-jsx:

{
  "compilerOptions": {
    "jsx": "react-jsx"
  }
}

Set the target environment

Use the target option to set the target environment for transformation. target can be set directly to the JavaScript language version, such as es6, es2020; it can also be set to several target environments, each target environment is an environment name followed by a version number, such as ['chrome58', 'edge16' ,'firefox57']. For a detailed introduction of the target option, please refer to esbuild - target.

target supports setting to the following environments:

  • chrome
  • edge
  • firefox
  • ie
  • ios
  • node
  • opera
  • safari
builderPluginEsbuild({
  loader: {
    target: 'chrome61',
  },
});

Disable transformation

Set loader to false to disable esbuild transformation, and Builder will continue to use Babel to transform the code.

builderPluginEsbuild({
  loader: false,
});

minimize

  • Type:
type MinimizeOptions = EsbuildMinifyOptions | false | undefined;
  • Default:
const defaultOptions = {
  css: true,
  target: 'es2015',
  format: builderTarget === 'web' ? 'iife' : undefined,
};

This option is used to enable minification for JavaScript and CSS.

If you want to modify the options, you can check the esbuild-loader documentation.

Set the target environment

Use the target option to set the target environment for minification.

builderPluginEsbuild({
  minimize: {
    target: 'chrome61',
  },
});

Disable minification

Set minimize to false to disable esbuild minification, and Builder will continue to use Terser to minify the code.

builderPluginEsbuild({
  minimize: false,
});

Limitations

Although esbuild can significantly improve the build performance of existing webpack projects, it still has certain limitations that require special attention.

Compatibility

As a compiler (i.e. loader capability), esbuild usually supports at least ES2015 (that is, ES6) syntax, and does not have the ability to automatically inject Polyfill.. If the production environment needs to downgrade to ES5 and below syntax, it is recommended to use SWC compilation.

You can specify the target syntax version by following config:

builderPluginEsbuild({
  loader: {
    target: 'es2015',
  },
});

As a code minify tool (i.e. minimize capability), esbuild can minify the code in production environment, and usually supports ES2015 syntax at least.

If you set the compressed target to es5, you need to ensure that all codes have been compiled to ES5 codes, otherwise it will cause esbuild compilation error: Transforming 'xxx' to the configured target environment ("es5") is not supported yet .

Therefore, for projects that need to be compatible with ES5 and below syntax in the production environment, please be careful to enable the minimize capability, and it is recommended to use SWC compression.

You can specify the target syntax version by following config:

builderPluginEsbuild({
  minimize: {
    target: 'es2015',
  },
});
Caution

Projects that need to be compatible with ES5 and below syntax in the production environment need to be careful to turn on the minimize config.

Not support Babel plugins

As a compiler, the syntax transformation function of the original Babel plugins such as babel-plugin-import is not available after esbuild is turned on. And since the bottom layer of the plugin uses esbuild's Transform API, it does not support esbuild plugins to customize the compilation process.

If you have requirements related to Babel plugins such as babel-plugin-import, you can use the SWC plugin.

Bundle Size

Although the compression speed of esbuild is faster, the compression ratio of esbuild is lower than that of terser, so the bundle size will increase, please use it according to the scenes. Generally speaking, esbuild is more suitable for scenes that are not sensitive to bundle size.

You can refer to minification-benchmarks for a detailed comparison between minimizers.