Esbuild
esbuild 是速度极快的 web 打包器,由 GO 语言编写
主要特性
- Extreme speed without needing a cache
- JavaScript, CSS, TypeScript, and JSX built-in
- A straightforward API for CLI, JS, and Go
- Bundles ESM and CommonJS modules
- Tree shaking, minification, and source maps
- Local server, watch mode, and plugins
常用选项
esbuild src/index.ts --outdir=dist
esbuild src/index.ts --splitting # Code splitting
esbuild src/index.ts --format=esm
esbuild src/index.ts --watchBundle
默认情况下,如果不指定 --bundle 选项,则不会解析其引入的包,例如:
esbuild src/index.ts --outdir=dist
esbuild src/index.ts --outdir=build --bundleimport { port } from './utils'
const str = "hello"
console.log({ str, port })export const port = 7890import { port } from "./utils";
const str = "hello";
console.log({ str, port });(() => {
// src/utils.ts
var port = 7890;
// src/index.ts
var str = "hello";
console.log({ str, port });
})();Stdin
通常,构建 API 调用采用一个或多个文件名作为输入。但是,此选项可用于在文件系统上根本不存在模块的情况下运行构建。它被称为stdin 。
import * as esbuild from 'esbuild'
let result = await esbuild.build({
stdin: {
contents: `export * from "./another-file"`,
// These are all optional:
resolveDir: './src',
sourcefile: 'imaginary-file.js',
loader: 'ts',
},
format: 'cjs',
write: false,
})charset
默认情况下,esbuild 只支持 ASCII,可以通过手动指定 charset
import * as esbuild from 'esbuild'
let js = 'let π = Math.PI'
(await esbuild.transform(js)).code
// 'let \\u03C0 = Math.PI;\n'
(await esbuild.transform(js, {
charset: 'utf8',
})).code
// 'let π = Math.PI;\n'format
format 用于指定输出格式
esbuild --format=iife
esbuild --format=iife --global-name=xyz
esbuild --format=esm
esbuild --format=cjsAsset names
该选项控制加载器设置为 file 时生成的附加输出文件的文件名
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['app.js'],
assetNames: 'assets/[name]-[hash]',
loader: { '.png': 'file' },
bundle: true,
outdir: 'out',
})有四个占位符可在资源路径模板中使用:
- [dir]
- [name]
- [hash]
- [ext]
Chunk names
Chunk names 也类似,但是不支持 dir 占位符
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['app.js'],
chunkNames: 'chunks/[name]-[hash]',
bundle: true,
outdir: 'out',
splitting: true,
format: 'esm',
})Out extension
可以将默认的 .js 和 .css 改为自定义的扩展
import * as esbuild from 'esbuild'
await esbuild.build({
entryPoints: ['app.js'],
bundle: true,
outdir: 'dist',
outExtension: { '.js': '.mjs' },
})External
import * as esbuild from 'esbuild'
import fs from 'node:fs'
fs.writeFileSync('app.js', 'require("fsevents")')
await esbuild.build({
entryPoints: ['app.js'],
outfile: 'out.js',
bundle: true,
platform: 'node',
external: ['fsevents', '*.png', '/images/*'],
})Packages
默认情况下,开启了--bundle 的 esbuild 将会递归解析所有 package,可以通过指定 --packages=external 选项,不解析外部选项。(即不以 . 或 .. 路径组件开头且不是绝对路径)标记为外部