ESBuild
约 4 分钟阅读
- evanw/esbuildGitHubevanw/esbuildevanw/esbuild · MIT, Go · bundler & minifier · used by Vite, Snowpack · roadmap · https://esbuild.github.io/api/ · https://esbuild.github.io/笔记:ESBuild
- MIT, Go
- bundler & minifier
- used by Vite, Snowpack
- roadmap
- esbuild.github.io/api
- esbuild.github.io
- 包含性能对比
- 目前暂无 swc
- esbuild#762GitHub Issueevanw/esbuild#762evanw/esbuild · MIT, Go · bundler & minifier · used by Vite, Snowpack · roadmap · https://esbuild.github.io/api/ · https://esbuild.github.io/笔记:ESBuild
- swc not ready
- esbuild.github.io
- Playground
- 可用来 Bundle ESM
- 可用来 Dev 时本地使用
- 推荐生产 Rollup - Vite
- 支持 iife, esm, cjs
- ES5+
- 不支持 emitDecoratorMetadata
- esbuild#257GitHub Issueevanw/esbuild#257
- thomaschaaf/esbuild-plugin-tscGitHubthomaschaaf/esbuild-plugin-tsc
- 会慢
- reflect-metadata
- 不支持 代码切分
- 不支持 HTML, CSS
- 不支持 TLA - WIP, iife
--banner:js='(async () => {' --footer:js='})()'- esbuild#253GitHub Issueevanw/esbuild#253
- 不支持 systemjs, amd
- esbuild#192GitHub Issueevanw/esbuild#192
- 不支持 umd - esbuild#507GitHub Issueevanw/esbuild#507
- 不支持 Bundle CSS Module esbuild#20GitHub Issueevanw/esbuild#20
- tsconfig.paths 不 bundled 时不会处理 esbuild#394GitHub Issueevanw/esbuild#394
- 写库只能用相对路径
- Support dynamic imports esbuild#700GitHub Issueevanw/esbuild#700
- dynamic import 不会 被 bundle
- Support jsx automatic runtime esbuild#334GitHub Issueevanw/esbuild#334
- 目前必须
import React, 需要调整 lint 配置 - Bundle 可考虑一次 inject esbuild.github.io/content-types
- eslint
'react/react-in-jsx-scope': 'error'
- 目前必须
- watch 使用 polling 实现 - 无任何操作也会消耗一点 CPU
- watch 无法检测到新文件
esbuild example.js --outfile=out.js
esbuild --bundle main.ts --outdir=dist --minify --sourcemap
# for Node
esbuild --bundle main.ts --outfile=dist/out.js --platform=node --format=esm
# bundle mutiple files
pnpm esbuild --outdir=dist $(jq '.bundle.input | join (" ")' package.json -r) --format=esm --charset=utf8 --target=chrome90 --sourcemap --bundle
# transform
esbuild $(find src \( -name '*.ts' -o -name '*.tsx' \)) --outdir=out
esbuild src/modules/*/{index.tsx,manifest.json} --serve=8000 --splitting --outdir=out --format=esm --bundle --charset=utf8 --target=chrome90 --sourcemap --minify
# stdin -> stdout
echo 'export const OK = process.env.NODE_ENV === "producation"' | pnpm exec esbuild --format=esm| flag | | ------------------------------- | ------------------------- | | --bundle | 包含所有依赖 | | --loader:.js=jsx | 允许 js 包含 jsx 语法 | | --define
=true | 替代 DEBUG | | --platform=browser,node,neutral | 默认 browser | | --external:@strapi | 作为外部依赖 | | --splitting | 拆分 chunk - 抽取公共部分 | | --charset=utf8 | 避免编码 | | --target | | --sourcemap=linked | |--servedir <dir> |
| --format <format> | iife, cjs, esm |
- --platform
- browser
- 隐含: --format=iife --condition=browser --define.env.NODE_ENV="production" --main-fields=browser,module,main
- 隐含: --format=iife --condition=browser --define.env.NODE_ENV="production" --main-fields=browser,module,main
- 使用 package.json 中的 browser
- 例如: path -> path-browserify
- main - 如果没有 browser 有 main 和 module 则会先用 main - cjs 更兼容
- node
- 隐含: --format=cjs --condition=node --main-fields=module,main --external=fs,url,http
- 自动 external node 的内建 api
- neutral
- 隐含: --format=esm
- browser
- --minify
- --minify-whitespace
- --minify-identifiers
- --minify-syntax - 移除 if(false) 代码
- Considerations
- --external:
/assets/*.png@foo/bar隐含@foo/bar/*
- --target
- chrome, edge, firefox, hermes, ie, ios, node, opera, rhino, safari
- 可以更详细
- esnext, es2020, es5, es5, node12, node19
- chrome90
- 也可以使用 supported 控制特性
- --supported - esbuild.github.io/api
- --sourcemap
- linked -
//# sourceMappingURL= - external - 无 sourceMappingURL
- inline
- both
- linked -
- --servedir
- 配合 script 使用
<script src="js/app.js"></script>
- --loader
- js - .js, .cjs, .mjs
- ts - .ts, .tsx, .mts, .cts
- jsx/tsx - .jsx
- json - .json
- css - .css
- text - .txt
- binary
- Uint8Array
- uint8array.buffer -> ArrayBuffer
- base64
- dataurl
- file
- copy
- 复制文件到 outdir - 修改 import 路径
- cdn url
- chrome90 会处理
?. - chrome70 会处理
??
analyze
只 bundle 内部文件
const path = require('path');
const pkg = require(path.resolve('./package.json'));
const external = [
...Object.keys(pkg.dependencies || {}),
...Object.keys(pkg.peerDependencies || {}),
'react-is',
'shallowequal',
'hoist-non-react-statics',
].sort();
console.log(`externals`, external);
require('esbuild').buildSync({
entryPoints: ['admin/src/components/Wysiwyg/index.js'],
loader: { '.js': 'jsx' },
format: 'esm',
bundle: true,
minify: false,
sourcemap: false,
target: ['esnext'],
outfile: 'dist/Wysiwyg.esm.js',
external,
logLevel: 'info',
});grep '^// ' ./dist/Wysiwyg.esm.js # bundled
grep '^// ' ./dist/Wysiwyg.esm.js | grep node_modules # bundled externalsPlugins
- esbuild/community-pluginsGitHubesbuild/community-plugins
- esbuild.github.io/plugins
- mdxjs.com/packages/esbuild链接mdxjs.com/packages/esbuildevanw/esbuild · MIT, Go · bundler & minifier · used by Vite, Snowpack · roadmap · https://esbuild.github.io/api/ · https://esbuild.github.io/笔记:ESBuild
- @mdx-js/esbuild
Spliting
- 试验阶段
- 提取多个 entrypoint 的 common 部分
- esbuild.github.io/api
esbuild home.ts about.ts --bundle --splitting --outdir=out --format=esmDynamic require of "fs" is not supported
- esbuild#1921GitHub Issueevanw/esbuild#1921
__dirname and __filename
- format 为 esm 的时候可能出现
- 添加 banner 解决
# __dirname, __filename 用动态 import 构建,避免冲突
npx esbuild --banner:js="import { createRequire } from 'module';const require = createRequire(import.meta.url);var __filename;var __dirname;{const {fileURLToPath} = await import('url');const {dirname} = await import('path');var __filename = fileURLToPath(import.meta.url); __dirname = dirname(__filename)};"var require, __filename, __dirname;
{
const { createRequire } = await import('node:module');
require ||= createRequire(import.meta.url);
}
{
const { fileURLToPath } = await import('node:url');
const { dirname } = await import('node:path');
__filename ||= fileURLToPath(import.meta.url);
__dirname ||= dirname(__filename);
}- esbuild#1921GitHub Issueevanw/esbuild#1921
The presence of "exports" here makes importing a directory forbidden:
- 需要添加 index.js
transpiling external modules
- remix#1423GitHub Issueremix-run/remix#1423
Transforming JavaScript decorators to the configured target environment ("node18.16.0") is not supported yet
- esbuild#104GitHub Issueevanw/esbuild#104
FAQ
不支持
- 函数体内的死代码消除
- 函数内联
- 跨语句的常量传播
- 对象形状建模
- 内存分配下沉
- 方法去虚拟化
- 符号执行
- JSX 表达式提升
- TypeScript 枚举的检测与内联
关联信息
反向链接、本文链接的其他页面和外部资料。
反向链接
- Web Dev FAQ笔记 · ESBuild
| abbr. | stand for | · | iife | Immediately Invoked Function Expression | · 在开发时 assert 错误 · invariant · 早期来自 React, flux
参考资料
GitHub16 条
- evanw/esbuild#1921github.com/evanw/esbuild/issues/1921
- egoist/play-esbuild/src/lib/esbuild.ts#L34github.com/egoist/play-esbuild/blob/main/src/lib/esbuild.ts
- esbuild/community-pluginsgithub.com/esbuild/community-plugins
- evanw/esbuildgithub.com/evanw/esbuild
- evanw/esbuild#104github.com/evanw/esbuild/issues/104
- evanw/esbuild#192github.com/evanw/esbuild/issues/192
- evanw/esbuild#20github.com/evanw/esbuild/issues/20
- evanw/esbuild#253github.com/evanw/esbuild/issues/253
- evanw/esbuild#257github.com/evanw/esbuild/issues/257
- evanw/esbuild#334github.com/evanw/esbuild/issues/334
- evanw/esbuild#394github.com/evanw/esbuild/issues/394
- evanw/esbuild#507github.com/evanw/esbuild/issues/507
- evanw/esbuild#700github.com/evanw/esbuild/issues/700
- evanw/esbuild#762github.com/evanw/esbuild/issues/762
- remix-run/remix#1423github.com/remix-run/remix/issues/1423
- thomaschaaf/esbuild-plugin-tscgithub.com/thomaschaaf/esbuild-plugin-tsc
其他外链10 条
- esbuild.github.io/apiesbuild.github.io/api
- esbuild.github.ioesbuild.github.io/
- esbuild.github.io/analyzeesbuild.github.io/analyze
- esbuild.github.io/content-typesesbuild.github.io/content-types
- esbuild.github.io/faqesbuild.github.io/faq
- esbuild.github.io/pluginsesbuild.github.io/plugins
- esbuild.github.io/tryesbuild.github.io/try
- gist.github.com/defunctzombie/4339901/49493836fb873ddaa4b8a7aa0ef2352119f69211gist.github.com/defunctzombie/4339901/49493836fb873ddaa4b8a7aa0ef2352119f69211
- mdxjs.com/packages/esbuildmdxjs.com/packages/esbuild
- unpkg.comunpkg.com/