esbuild note - 1

154 阅读3分钟

快速创建一个项目

mkdir esbuild-learn
cd esbuild-learn
npm init -y

输出

{
  "name": "esbuild-learn",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

  "keywords": [],
  "author": "",
  "license": "ISC"
}

安装各种工具

npm i -D esbuild webpack webpack-cli babel-loader @babel/preset-react
npm i react react-dom

安装esbuild同时安装webpack,用于后面的打包对比。

创建示例项目

mkdir src

项目源代码

src下创建app.jsxindex.jsx两个文件;在项目根下创建tpl.html

// app.jsxwq2
import React from 'react'

export default () => {
    return <h1>Hello ESBuild</h1>
}
// index.jsx
import React from 'react'
import ReactDOM from 'react-dom'
import App from './app.jsx'

ReactDOM.render(<App />, document.getElementById('app'))
<!-- tpl.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="app"></div>
<script type="text/javascript" src="./index.js"></script>
</body>
</html>

webpack.config.js

由于webpack配置过于复杂,单靠命令行很难实现完整配置,所以需要单独创建一个配置文件。

module.exports = {
    entry: './src/index.jsx',
    mode: 'production',
    output: {
        path: require('path').resolve('dist'),
        filename: 'index.js'
    },
    module: {
        rules: [
            {
                test: /\.jsx?/i,
                use: [{
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-react']
                    }
                }]
            }
        ]
    },
}

工程目录

src/
 - app.jsx
 - index.jsx
tpl.html
package-lock.json
package.json

创建运行脚本

只考虑*nix的环境,在尽量少依赖其他插件和工具的情况下,完成项目构建。

需要考虑以下过程:

  • 构建前清空输出目录dist
  • 构建后复制tpl.html到输出目录并更名为index.html

清空输出目录 script.clean

rm -rf ./dist

复制html模版 script.copy

cp ./tpl.html ./dist/index.html

使用esbuild打包 script.build:es

esbuild ./src/index.jsx --bundle --outfile=./dist/index.js --minify

这里的参数指令可以到esbuild官网直接复制过来,改一改就好。其中--minify是开启压缩代码的参数。

使用webpack打包 script.build:wp

webpack --config=webpack.config.js

这个--config参数可加可不加,因为用的是config的默认名称。

流程控制

使用post pre将几个脚本串起来,scripts最终的样子:

{
    "scripts": {
        "copy": "cp ./tpl.html ./dist/index.html",
        "clean": "rm -rf ./dist",
        "build:es": "esbuild ./src/index.jsx --bundle --outfile=./dist/index.js --minify",
        "build:wp": "webpack --config=webpack.config.js",
        "postbuild:es": "npm run copy",
        "postbuild:wp": "npm run copy",
        "prebuild:es": "npm run clean",
        "prebuild:wp": "npm run clean"
    }
}

运行

使用webpack打包

% npm run build:wp

> esbuild-learn@1.0.0 prebuild:wp
> npm run clean


> esbuild-learn@1.0.0 clean
> rm -rf ./dist


> esbuild-learn@1.0.0 build:wp
> webpack --config=webpack.config.js

asset index.js 127 KiB [emitted] [minimized] (name: main) 1 related asset
orphan modules 126 bytes [orphan] 1 module
modules by path ./node_modules/ 192 KiB
  modules by path ./node_modules/react/ 8.5 KiB
    ./node_modules/react/index.js 189 bytes [built] [code generated]
    ./node_modules/react/cjs/react.production.min.js 8.32 KiB [built] [code generated]
  modules by path ./node_modules/react-dom/ 175 KiB
    ./node_modules/react-dom/index.js 1.32 KiB [built] [code generated]
    ./node_modules/react-dom/cjs/react-dom.production.min.js 173 KiB [built] [code generated]
  modules by path ./node_modules/scheduler/ 6.84 KiB
    ./node_modules/scheduler/index.js 197 bytes [built] [code generated]
    ./node_modules/scheduler/cjs/scheduler.production.min.js 6.65 KiB [built] [code generated]
  ./node_modules/object-assign/index.js 2.17 KiB [built] [code generated]
./src/index.jsx + 1 modules 310 bytes [built] [code generated]
webpack 5.65.0 compiled successfully in 3130 ms

> esbuild-learn@1.0.0 postbuild:wp
> npm run copy


> esbuild-learn@1.0.0 copy
> cp ./tpl.html ./dist/index.html

关键信息

asset index.js 127 KiB [emitted] [minimized] (name: main) 1 related asset
webpack 5.65.0 compiled successfully in 3130 ms

具体查看一下输出信息:

% ls -l dist
total 272
-rw-r--r--  1 kema  staff     162  1  5 21:46 index.html
-rw-r--r--  1 kema  staff  129770  1  5 21:46 index.js
-rw-r--r--  1 kema  staff     788  1  5 21:46 index.js.LICENSE.txt

汇总

size: 129770 byte
time: 3130 ms

使用esbuild打包

% npm run build:es

> esbuild-learn@1.0.0 prebuild:es
> npm run clean


> esbuild-learn@1.0.0 clean
> rm -rf ./dist


> esbuild-learn@1.0.0 build:es
> esbuild ./src/index.jsx --bundle --outfile=./dist/index.js --minify


  dist/index.js  129.5kb

⚡ Done in 32ms

> esbuild-learn@1.0.0 postbuild:es
> npm run copy


> esbuild-learn@1.0.0 copy
> cp ./tpl.html ./dist/index.html

关键信息

dist/index.js  129.5kb
⚡ Done in 32ms

具体查看一下输出信息:

% ls -l dist      
total 272
-rw-r--r--  1 kema  staff     162  1  5 21:51 index.html
-rw-r--r--  1 kema  staff  132591  1  5 21:51 index.js

汇总

size: 132591 byte
time: 32 ms

结论

打包工具文件尺寸(byte)耗时(ms)
webpack1297703130
esbuild13259132

至于为什么esbuild总会多出差不多3kb的尺寸,还没深入研究。单从近100倍的耗时提升角度来看,这3kb是完全可以接受的。

以上。