Replies: 1 comment
-
可增加 4 与 5 的编译速度对比,鼓励开发者对老项目进行升级。 |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
概述
支持开发者选择使用 Webpack5 编译小程序、H5 应用。
动机
Webpack5 发布已有两年时间,功能足够稳定,同时其持久化缓存、模块联邦、更优的 Tree Shaking 等特性都为项目的编译流程提供了更好的解决方案。因此 Taro 将对基于 Webpack4 的编译系统进行重构,实现对 Webpack5 的支持,改善编译时的性能与体验。
使用案例
开发者可以自由选择编译工具。
详细设计
1. 新增依赖包
@tarojs/webpack5-runner
升级 Webpack5 会带来很多差异,为了不影响目前基于 Webpack4 的项目,单独新增依赖包
@tarojs/webpack5-runner
,并将小程序和 H5 的编译时逻辑整合在其中。同时,旧项目需要卸载
@tarojs/mini-runner
和@tarojs/webpack-runner
,并更新 lockfile。2. 更新 Plugins & Loaders
把 Taro 使用到的 Plugins 和 Loaders 升级到兼容 Webpack5 的最新版本。
3. 废弃
file-loader
和url-loader
使用 Webpack5 的 asset-modules 功能代替
file-loader
和url-loader
。兼容双方都支持的配置功能,废除在asset-modules
中找不到对应的file-loader
、url-loader
配置。4. 不改动
@tarojs/loader
Webpack 内部支持了 this.getOptions,但为了兼容 Webpack4 和维护的方便,不对
@tarojs/loader
进行改造。5. 持久化缓存
Webpack5 的持久化缓存功能是最重要的特性之一,能极大提升再次编译时的速度。但同时也引入了如何使缓存失效的问题。
Taro 遵循 Webpack “编译安全比编译速度重要” 的理念,默认不开启持久化缓存的功能。
因此我们需要:
使缓存失效的默认策略
config/index.js
及其依赖时需要使缓存失效。持久化缓存的默认配置
当
cache.enable
为true
时, Webpack 默认的cache
配置为:6. JS 压缩
新增
jsMinimizer
编译配置,开发者可以选择使用terser
或esbuild
对 JS 进行压缩。默认使用
terser
,因为目前两者的压缩效果还是有差距。新增
esbuild
编译配置,用于配置esbuild
压缩工具。7. CSS 压缩
新增
cssMinimizer
编译配置,开发者可以选择使用csso
、esbuild
或@parcel/css
对 CSS 进行压缩。使用
css-minimizer-webpack-plugin
代替csso-webpack-plugin
,支持csso
、esbuild
、@parcel/css
三种 CSS 压缩工具。默认使用
csso
,因为@parcel/css
实测时容易报错,稳定性不高、而小型项目使用esbuild
代替csso
收益不高。8. 关于接入 SWC
SWC 定位是代替 Babel,对标实现了很多 Babel 的功能,基础的语法转换应该问题不大。问题在于需要使用 SWC 插件系统把自定义的 Babel 插件实现一遍,而它的插件系统目前还难以对标 Babel 的功能(没有 path 只有节点、需要手拼 AST 节点等问题)。
SWC 对比 Babel:
browserlist
的支持,也实现了对标@babel/preset-env
的target
的功能。@babel/preset-env
的useBuildIns
、corejs
的能力,支持entry
、usage
两种用法。但没有@babel/plugin-transform-runtime
的 core-js aliasing 能力,也就是没有作用域隔离。@babel/plugin-transform-runtime
的 helper aliasing 和 regenerater aliasing 功能,其中regenerator runtime
需要宿主自行安装。综上,目前还不能使用 SWC 代替
babel-loader
。Taro 的切入点:
@swc/register
代替@babel/register
,提升加载config.js
的速度。@swc/jest
代替ts-jest
,提升测试用例的编译速度。9. 依赖预编译
受 UmiJS mfsu 特性的启发,我们可以预先把用户的 node_modules 依赖打包为一个 Module Federation 的 remote 应用,再次编译时可以免去 Webpack 对这些依赖的编译,从而提升编译速度。
依赖预编译可以分为三步:
9.1. 收集依赖
参考 Vite 使用 esbuild 对用户项目进行 bundle,并编写插件分析
import
和require
语句,收集 node_modules 依赖。注意点:
9.2. 打包依赖
参考 Vite 使用 esbuild 对上述收集到的依赖进行 bundle(ESM),缓存在用户项目里的
node_modules/.taro/prebundle
中。注意点:
virtual module
实现对输出目录的扁平化(flatten)9.3. 打包 Module Federation Remote 应用
把上述 esbuild 的 bundle 打包为 Module Federation 的 remote 应用,供开发者的应用(Host)使用。
注意点:
webpack/lib/container/ContainerPlugin
。9.4. 打包开发者的应用(Host),开启 Module Federation
注意点:
webpack/lib/container/ContainerReferencePlugin
。缺陷
替代选择
N/A
适配策略
Beta Was this translation helpful? Give feedback.
All reactions