esbuild api整理

Published: · LastMod: September 11, 2022 · 1555 words

esbuild 🔗

基础api 🔗

option类型默认值说明
bundlebooleanfalse把从入口开始的文件打包成一个bundle,设为true时,会把文件引用的其他文件也打包进来,默认为false,则不会打包其他引用文件
defineobject{}提供一种替换文件内常量的行为,可以用作替换环境变量
entryPointsarray[]入口文件数组,可以有多个入口一起打包
externalarray[]排除打包的一些其他类库或者资源,可以使用通配符
formatstringiife/cjs/esm最终打包出来的文件输出格式
injectarray[]可以用来注入一些跨平台时兼容的代码
loaderobject{}引用资源也是采用loader的形式进行解析
minifybooleanfalse是否压缩代码
outdirstring''最后打包输出的目录
outfilestring''最终打包的bundle的文件名
platformstringnode/browser最后打包输出的平台
servestring''开发模式下用作实时响应文件变动,即时打包
sourcemapbooleanfalse最后是否生成sourcemap文件
splittingbooleanfalse打包是否进行代码分割
targetarray[]chrome/ edge/ firefox/ hermes/ ie/ ios/ node/ opera/ rhino/ safari
watchbooleanfalse文件监听模式
writebooleanfalse是否写入到文件系统/输出到内存中
option类型默认值说明
analyzebundle分析功能
assetNames引用的静态资源的重新命名
banner不同资源添加不同的顶部注释代码
charsetstringascII输出文件的字符编码
chunkNamesstring输出bundle的文件名, 于此同时需要打开splitting, 设置format为esm
colorstring控制台输出是否带颜色标识
drop[]是否丢弃debugger和console
footerstring不同资源添加不同的底部注释代码
globalNamestringiife模式下挂载全局变量的名称
ignoreAnnotationsboolean是否忽略tree-shaking默认注解
jsxstring编译jsx语法的能力

内置loader 🔗

已经内置的loader包括以下几种

  • js
  • ts/tsx
  • jsx
  • json
  • css
  • text // 读取文本字符串
  • binary // 二进制文件以Uint8Array引入
  • base64 // base64形式
  • dataurl // 图片文件以base64的形式插入到js中
  • file // 文件
  • copy // 复制

插件 🔗

社区插件生态

https://github.com/esbuild/community-plugins

option案例 🔗

analyze 🔗

esbuild 分析模式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18

(async () => {
  let esbuild = require('esbuild')

  // 打包结果
  let result = await esbuild.build({
    entryPoints: ['example.jsx'],
    outfile: 'out.js',
    minify: true,
    metafile: true,
  })

  // 使用analyzeMetafile API进行分析
  let text = await esbuild.analyzeMetafile(result.metafile, {
    verbose: true,
  })
  console.log(text)
})()

assetNames 🔗

静态资源的重新命名

1
2
3
4
5
6
7
require('esbuild').buildSync({
  entryPoints: ['app.js'],
  assetNames: 'assets/[name]-[hash]',
  loader: { '.png': 'file' },
  bundle: true,
  outdir: 'out',
})
1
2
3
4
5
6
7
8
require('esbuild').buildSync({
  entryPoints: ['app.js'],
  banner: {
    js: '//comment',
    css: '/*comment*/',
  },
  outfile: 'out.js',
})

chunkNames 🔗

输出的chunk的重新命名

1
2
3
4
5
6
7
8
require('esbuild').buildSync({
  entryPoints: ['app.js'],
  chunkNames: 'chunks/[name]-[hash]',
  bundle: true,
  outdir: 'out',
  splitting: true, // 必须设置
  format: 'esm',// 必须设置
})

color 🔗

输出的日志是否带颜色标识

1
2
3
require('esbuild').transformSync(js, {
  color: true,
})

drop 🔗

1
2
3
4
require('esbuild').buildSync({
  entryPoints: ['app.js'],
  drop: ['console', 'debugger'],
})

globalName 🔗

1
2
3
4
5
let js = 'module.exports = "test"'
require('esbuild').transformSync(js, {
  format: 'iife',
  globalName: 'xyz',
})

ignoreAnnotations 🔗

忽略注解

默认情况下

  • 行内的/* @__PURE__ */注释告诉esbuild,当代码中没有使用到该函数时,就可以被移除掉
  • package.json中配置的sideEffects告诉编译器,当文件引入后没有被使用时,就不会被打包到bundle中去

当打开忽略注解后,esbuild编译器就会忽略上面的配置注解,自动分析打包

jsx 🔗

告诉编译器编译jsx语法的能力

  • transform
  • preserve
  • automatic
1
2
3
4
require('esbuild').transformSync('<div/>', {
  jsx: 'preserve',
  loader: 'jsx',
})

jsx factory 🔗

设置jsx编译后的方法名

默认jsx元素会被编译成React.createElement元素

1
2
3
4
5
<div>Example text</div>

// ==
// 编译后结果
React.createElement("div", null, "Example text");

或者在transform的时候设置

1
2
3
4
require("esbuild").transformSync("<div/>", {
  jsxFactory: "h",
  loader: "jsx"
})

如果是在使用typescript开发,可以设置tsconfig.json

1
2
3
4
5
{
  "compilerOptions": {
    "jsxFactory": "h"
  }
}

或者在使用时添加注释 // @jsx h

Pure 🔗

特殊注释/* @__PURE__ */ 或者 /* #__PURE__ */是用来标注特殊函数,在打包时可以进行优化,如果没有使用到这个函数,就不会最终打包到bundle中

Tree shaking 🔗

摇树优化

当项目中有相应的函数没有被使用到时,编译器在打包的时候会对函数进行搜集,如果没有使用到最终会被移除出bundle

esbuild的tree shaking依赖于es6的 import 和 export语法, CommonJS模块就不能支持Tree shaking

默认esbuild的tree shaking只有在format为iife的情况下才是打开的,其他模式下都是关闭的,可以手动设置为true

1
2
3
4
5
require('esbuild').buildSync({
  entryPoints: ['app.js'],
  treeShaking: true,
  outfile: 'out.js',
})