使用 esbuild 对 js 进行打包

更新日期: 2022-05-03 阅读次数: 299 字数: 770 分类: Javascript

之前只用过 webpack 进行 js 项目打包,但其实都是用的现成的脚手架,不需要过多的自己配置。 这次是纯手动创建的项目,并没有任何脚手架代码及配置,所以我想尝试自己配置一遍。

为何选择 esbuild

粗略调研了一圈,webpack, rollup, vite, esbuild。

  • webpack 确实最强大,我甚至花了两天时间看了一本书,虽然学到不少,但用不到那么多配置
  • vite 感觉是人为推广,跟风严重,不太想去了解,而且开发环境是基于 esbuild。我对知乎上一致好评的技术选型有天然的抵触情绪
  • rollup 官方教程不错
  • 我决定尝试 esbuild,仅仅是因为 esbuild 是用 go 写的。打包速度比 webpack 快 10 倍以上。有了 antd pro 项目中 webpack 打包的糟糕体验,我非常想尝试一下秒完成的快感

虽然 flicking 官方推荐的 webpack / rollup

https://naver.github.io/egjs-flicking/docs/quick-start

Or, you can rather import them if you're using a bundler like webpack or rollup.

import Flicking from "@egjs/flicking";
import "@egjs/flicking/dist/flicking.css";

安装 esbuild

项目中第一次安装 esbuild:

npm install esbuild

确认安装成功:

> npx esbuild --version
0.14.38

tips: esbuild 使用的是本地安装,而非全局。如果不用 npx 就得写 node_modules 的子路径。

npm 包管理的作用范围

我是在 package.json 所在目录的下二级目录运行的 npm install esbuild,然后发现依赖更新还是原来的 package.json。 看来跟 git 的管理类似,都是逐层向上寻找配置文件。之前做的 frontend / backend 目录分离真是太正确了,避免了依赖管理混乱。

文件变化:

> git status

modified:   ../../package-lock.json
modified:   ../../package.json

依赖记录:

> git diff ../../package.json
+  },
+  "dependencies": {
+    "esbuild": "^0.14.38"

拉取已有项目然后安装 esbuild

如果项目的 package.json 中已经包含了 esbuild 的依赖, 直接运行

tyarn

即可自动安装所有依赖。确保所有开发环境的 esbuild 版本号一致。

示例

以 flicking 插件为例

https://naver.github.io/egjs-flicking/Plugins

tyarn add @egjs/flicking-plugins

配置文件

require("esbuild").build({
  absWorkingDir: __dirname,
  entryPoints: ["js/main.js"],
  outfile: "public/js/main.js",
  watch: true,
  bundle: true,
  minify: true,
})
.then(() => console.log("⚡ Done"))
.catch(() => process.exit(1));

使用 absWorkingDir 是为了使用配置文件的相对路径来指定输入文件和输出文件。 因为后台我搞了 N 个主题模板,每个主题有不同的 esbuild 配置文件,及不同的需要打包的文件。

执行打包操作

node templates/theme_1/build.js

测试了一下,打包效果完全满足需求。速度上,确实是秒完成。

Makefile

因为一个项目只会使用一个主题,所以 Makefile 从 golang 项目的 .env 配置文件中读取主题路径,动态执行 esbuild 打包。

include .env

THEME_PATH := ./templates/$(THEME)

.PHONY: esbuild 
esbuild:
	node templates/$(THEME_PATH)/build.js

能否 import from cdn

https://stackoverflow.com/questions/34607252/es6-import-module-from-url

> node templates/theme_1/build.js
✘ [ERROR] Could not resolve "@egjs/flicking"

    ../../node_modules/@egjs/flicking-plugins/dist/plugins.esm.js:9:56:
      9 │ import { EVENTS, DIRECTION, FlickingError, clamp } from '@egjs/flicking';
        ╵                                                         ~~~~~~~~~~~~~~~~

  You can mark the path "@egjs/flicking" as external to exclude it from the bundle, which will
  remove this error.

爱评论不评论