极速 JavaScript 打包器:esbuild

2023-11-16 15:18:15 浏览数 (1)

引言

--

esbuild是一个快速、可扩展的JavaScript打包器和压缩器,它的目标是成为最快的打包器。它使用Go编写,可以在几乎瞬间内完成大多数项目的构建。在本文中,我们将深入了解esbuild,并探讨其如何实现如此出色的性能。

什么是esbuild?


esbuild 是一款基于 Go 语言开发的 javascript 构建打包工具,相比传统的构建工具,主打性能优势。同样规模的项目,使用 Esbuild 可以将打包速度提升 10 - 100 倍,这对广大一直饱受 Webpack 缓慢打包速度折磨的开发人员来说,简直就是福音。

esbuild的特点


1. 极快的构建速度

esbuild被设计为最快的JavaScript打包器之一。它使用Go编写,并且可以在几乎瞬间内完成大多数项目的构建。这使得它成为处理大型代码库和快速迭代开发过程中不可或缺的工具。

2. 可扩展性

esbuild支持插件系统,这使得开发人员可以根据自己的需求进行自定义配置。插件系统还允许开发人员添加自定义转换器和加载程序。

3. 支持多种模块格式

esbuild支持多种模块格式,包括CommonJS、ES6模块、AMD和UMD等。这使得开发人员可以轻松地将现有代码库迁移到esbuild中。

4. 支持TypeScript

esbuild支持TypeScript,并且可以直接处理TypeScript文件。这意味着开发人员无需安装额外的TypeScript编译器即可使用TypeScript。

5. 支持JSX

esbuild支持JSX,并且可以直接处理JSX文件。这意味着开发人员无需安装额外的Babel插件即可使用JSX。

esbuild如何实现如此出色的性能?


1. Go语言

esbuild使用Go语言编写,这使得它比其他JavaScript打包器更快。Go语言具有出色的并发性能和内存管理功能,这使得它非常适合用于构建工具。

2. 并行化处理

esbuild使用并行化处理来加速构建过程。它会将输入文件分成多个块,并在多个CPU核心上同时处理每个块。这样做可以显著提高构建速度。

例如,在一个包含10个JavaScript文件的项目中,如果将输入文件分成5个块,则每个块包含2个JavaScript文件。然后,在4核CPU上运行时,每个核心将同时处理一个块中的2个JavaScript文件。

3. AST优化

esbuild会对输入代码进行AST(抽象语法树)优化以提高性能。AST优化是一种通过修改代码结构来提高执行效率的技术。

例如,在一个包含大量重复代码或未使用变量/函数等未优化代码段的项目中,AST优化可以通过删除重复代码或未使用变量/函数等未优化代码段来减小输出文件大小并提高性能。

4. Tree shaking

Tree shaking是一种通过删除未使用代码来减小输出文件大小的技术。esbuild会对输入代码进行Tree shaking以减小输出文件大小并提高性能。

例如,在一个包含大量未被引用或未被执行函数/变量等冗余代码段的项目中,Tree shaking可以通过删除冗余代码段来减小输出文件大小并提高性能。

示例

下面是一个简单示例:

代码语言:javascript复制
// index.js
import { add } from './math.js';

console.log(add(1, 2));

// math.js
export function add(a, b) {
  return a   b;
}

export function subtract(a, b) {
  return a - b;
}

运行以下命令:

npx esbuild index.js --bundle --outfile=out.js

则会生成以下输出:

代码语言:javascript复制
// out.js
function add(a, b) {
  return a   b;
}

console.log(add(1, 2));

在此示例中,由于subtract函数没有被引用或执行,则Tree shaking会将其删除以减小输出文件大小并提高性能。

esbuild缺点


尽管esbuild具有许多优点,但它也有一些缺点。下面是一些esbuild的缺点:

  • 社区生态相对较小
  • 没有 TS 类型检查
  • 不支持代码分割
  • 不支持多种语言(比如vue)
  • 不能操作 AST
  • 不支持装饰器语法
  • 产物 target 无法降级到 ES5 及以下,不能兼容一些低版本浏览器

基本配置


入口文件

在使用esbuild时,需要指定入口文件。可以使用--entry选项指定入口文件,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js
输出文件

在使用esbuild时,需要指定输出文件。可以使用--outfile选项指定输出文件,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js
模块格式

在使用esbuild时,需要指定模块格式。可以使用--format选项指定模块格式,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js --format=esm

支持的模块格式包括:esm(ES6模块)、cjs(CommonJS)、iife(立即执行函数)、amd(AMD)和umd(UMD)。

target

target选项用于指定输出代码的目标环境。可以使用--target选项指定目标环境,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js --target=es2015

支持的目标环境包括:es2015(ES6)、es2016(ES7)、es2017(ES8)、es2018(ES9)、es2019(ES10)、es2020(ES11)和esnext(最新版本)。

platform

platform选项用于指定输出代码的平台。可以使用--platform选项指定平台,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js --platform=node

支持的平台包括:browser(浏览器)和node(Node.js)。

external

在使用esbuild时,你可以选择将某些模块排除在输出文件之外。可以使用--external:module-name[=variable-name]... 选项排除模块,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js --external:react --external:react-dom

在此示例中,我们将React和React DOM排除在输出文件之外。

banner和footer

在使用esbuild时,你可以选择在输出文件的开头或结尾添加自定义文本。可以使用 --banner:file=path/to/banner.txt--footer:file=path/to/footer.txt 选项添加文本,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.js  --banner:file=header.txt  --footer:file=footer.txt

在此示例中,我们将header.txt添加到输出文件开头,并将footer.txt添加到输出文件结尾。

高级配置


插件系统

esbuild支持插件系统,这使得开发人员可以根据自己的需求进行自定义配置。插件系统还允许开发人员添加自定义转换器和加载程序。 例如,在使用Less或Sass等CSS预处理器时,你可以使用相应的插件来实现。以下是一个示例:

代码语言:javascript复制
// esbuild.config.js
const sassPlugin = require('esbuild-plugin-sass');
module.exports = {
  entryPoints: ['index.js'],
  outfile: 'out.js',
  plugins: [sassPlugin()],
};
自定义插件

除了使用现有插件外,你还可以编写自己的插件来扩展esbuild。以下是一个示例:

代码语言:javascript复制
// my-plugin.js
module.exports = (options = {}) => ({
  name: 'my-plugin',
  setup(build) {
    build.onLoad({ filter: /.txt$/ }, async (args) => {
      const contents = await fs.promises.readFile(args.path, 'utf8');
      return { contents };
      });
    },
});
// esbuild.config.js
const myPlugin = require('./my-plugin');
module.exports = {
  entryPoints: ['index.js'],
  outfile: 'out.js',
  plugins: [myPlugin()],
};

在此示例中,我们编写了一个名为my-plugin的插件,并将其添加到了配置文件中。该插件会在加载.txt文件时读取其内容并返回给构建器。

压缩代码

在使用esbuild时,你可以选择是否压缩代码以减小输出文件大小并提高性能。可以使用--minify选项压缩代码,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.min.js --minify
调试代码

在使用esbuild时,你可以选择是否生成调试信息以便于调试代码。可以使用--sourcemap选项生成调试信息,例如:

代码语言:shell复制
npx esbuild --entry=index.js --outfile=out.min.js --minify --sourcemap=inline

支持的sourcemap类型包括:inline(内联)、external(外部)和sources-content(包含源代码内容)。

结论

--

总之,如果你正在寻找一个快速、可扩展且易于配置的JavaScript打包器和压缩器,那么你应该考虑使用esbuild。它具有极快的构建速度、可扩展性、支持多种模块格式、支持TypeScript和JSX等特点,并且通过Go语言、并行化处理、AST优化和Tree shaking等技术实现了出色的性能表现。在选择使用esbuild时,请考虑其优点和缺点,并根据自己项目的需求进行选择。

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

0 人点赞