另辟蹊径的构建提速法

题图:markusspiske @ unsplash.com

最近有些关于 webpack 的想法,和大家分享下。

现在的项目构建基本被 webpack 包揽,不管啥项目都上 webpack,我们的框架和工具也都是基于 webpack 实现,遇到问题了也是基于 webpack 做优化。比如语雀,是一个非常大的项目,构建产物有 200 多个文件,耗时 5 到 10 分钟。由于 uglifyjs 需要消耗大量内存,以至于经常 OOM。

但 webpack 真是普适的银弹吗?针对一些场景,我们是否可以不用 webpack,是否有比 webpack 更合适的方案?合适在哪里?webpack 的功能是否我们都要用到?

下面我把收集到的信息整理下,如果我要自研构建工具,可能会考虑他们。

systemjs

支付宝小程序的构建部分开始是我负责的,用的 webpack,极尽了优化方案,最终还要 5s 多启动时间,windows 下则更慢。后来 @pigcan 负责后,基于 systemjs 实现了一套构建,据说秒开!大家可以验证下。微信小程序应该也是这个路子。

  1. systemjs 本身不够完善,需要做很多额外的事情
  2. node 原生模块的 shim 和 sham
  3. npm 依赖的 resolve 和合并

还有 stackblitz 的在线构建方案也是基于 systemjs,他们有开源

babel 竞争者

babel 只构建流程中非常重要的一环,优化他就能优化整个流程。

sucrase

据说比 babel 快 20 倍。

babel 编译慢是因为他做的事多,并且禁用 babel 功能(比如少开语言特性)并不能有效提速。

因为 babel 的编译流程是这样,

  1. Tokenize,把源码转为 code 流
  2. 解析 token 流为 AST
  3. 遍历 AST,为每个变量生成 scope 信息
  4. 执行 transform 插件,生成新的 AST
  5. 输出最终 AST

而禁用功能只能减少第四步所需要的时间。

sucrase 忽略了大部分的步骤,比如 Tokenize 时不生成完整的 AST,Transform 时很多操作通过文本替换进行等等。

swc

rust 版的 babel。

es-serve

面向现代浏览器,代替 webpack-dev-server,处理 node resolve 规则,我觉得和上面的 surcrase 结合应该会更快。

  1. 借助 babel-plugin-bare-import-rewrite 支持 node resolve
  2. 通过浏览器的 import 实现资源加载
  3. 由于原生 import 不支持 css、图片等,所以需额外处理
  4. 处理了 History API fallback
  5. 不支持 HMR

parcel

webpack 竞争者。

出来时很抢眼球,今天上去看了一眼,感觉维护跟不上,github 上 300 多个 Bug 未修,不是每个人都像 sokra 一样不开社交软件的。。

配置式研发

很多建站工具都是这个路子,把需要的库和功能全部打包好,用户通过配置的方式进行开发,内部外部都有很多这样的例子,内部比如 poker、可视化建站、金蝉等等。

说回我们的场景,比如 ant-design-pro 这个特定场景,我们是否可以把所有功能全部打包好,然后通过配置,以及允许用户编写部分代码的方式,来做基于 ant-design-pro 的开发?

我的想法

如果我来做,

  1. build 和 dev 走同一套
  2. es-serve 太超前,支持 import 的浏览器毕竟还不多,不能上生成环境
  3. systemjs + babel 和 postcss 的组合会比较合适,babel 可以尝试用 sucrase 或 swc 替换,需要做一些合并,合并到一级依赖会比较合适