

Taro 3.5 beta 编译提速,支持 Webpack5、React 18...
source link: https://www.fly63.com/article/detial/11540
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

编译速度一直是困扰开发者的头等问题,现阶段大型 Taro 项目即使在增加了 cache-loader 、 thread-loader 等优化手段后,编译耗时仍高居不下。因此在 v3.5 版本中 Taro 重点对编译系统进行了重构,引入对 webpack5 的支持,改善小程序 & H5 编译时的性能与体验。(除此之外,Taro 也正在落地对于 Vite 的支持,届时开发者将可以自由地选择编译工具。)
同时,Taro v3.5 还带来了兼容 react 18、H5 MPA 等新特性,欢迎各位同学升级试用~
一、编译提速
为了改善编译性能,Taro 主要做了以下事情:
- 支持 Webpack5
- 基于模块联邦的依赖预编译
- 支持使用 esbuild 压缩 JS,使用 esbuild 或 @parcel/css 压缩 CSS
- 使用 @swc/register 代替 @babel/register
接下来将简单聊聊 Webpack5 与依赖预编译,关于编译提速的完整实现细节请参阅RFC 文档。
1. Webpack5
Webpack5 发布已有两年时间,功能足够稳定,同时其持久化缓存、模块联绑、更优的 Tree Shaking 等特性都为项目的编译流程提供了更好的解决方案。
其中的 持久化缓存功能 是最重要的特性之一,能极大提升再次编译时的速度。但同时也引入了如何使缓存失效的问题。
Taro 遵循 Webpack “编译安全比编译速度重要” 的理念,默认不开启持久化缓存。当开发者设计好缓存策略后,强烈建议开启持久化缓存。详细配置请参考mini.cache。
2. 依赖预编译
Webpack5 另一个重要的特性要数 模块联邦(Module Federation) 。受UmiJS mfsu 特性的启发,可以预先把项目的 node_modules 依赖打包为一个模块联邦 remote 应用,再次编译时 Webpack 则无需再对依赖进行编译,从而提升编译速度。
依赖预编译可以分为三步:
- 打包 Module Federation Remote 应用
Taro 参考Vite 使用了 esbuild 收集用户使用到的第三方依赖,并分别进行打包。打包后的模块会作为 Webpack 的 entry,最终打包为模块联邦 Remote 应用,供主应用(Host)消费。实现细节请参考RFC 文档。
Taro 会在小程序环境的 dev 模式下默认开启依赖预编译功能。首次编译时,因为使用了 esbuild 打包第三方依赖,所以会比普通编译稍快。二次编译时,Taro 能直接复用 Remote App,Webpack 只需编译业务代码,因此根据不同项目会有不同的编译提速效果。
依赖预编译的流程图:

3. 提速效果
以NutUI 组件示例库为例,分别测试 dev 与 prod 环境下编译微信小程序的编译提速效果:


可以看出:
- 在 dev 环境下因为 Taro 默认开启了依赖预编译,因此 Webpack5 首次编译速度比 Webpack4 稍快。而 prod 环境没有默认开启依赖预编译,因此两者速度相当(而且 Webpack5 需要写入缓存,可能会比 Webpack4 稍慢)。
- 无论是 dev 还是 prod 环境,在完全命中缓存的最优情况下,Webpack5 的编译速度都能得到极大提升。即使是修改源码导致了部分缓存失效时,编译速度仍然比首次编译快得多。
旧项目升级后需要安装 Webpack5 的相关依赖才能正常编译,详情请参考下文的【升级指南】部分。
简单修改 Taro 的编译配置即可开启 Webpack5、持久化缓存、依赖预编译等功能:
/** config/index.js */
const config = {
// 自定义编译工具,可选 'Webpack4' 或 'Webpack5'
compiler: {
type: 'webpack5',
// 依赖预编译配置
prebundle: {
enable: true
}
},
// 持久化缓存配置
cache: {
enable: true
}
}
二、兼容 React18
React 官方正式发布了 react v18版本,带来了 Automatic Batching、Transitions 和 Concurrent 等诸多新特性,提升了React性能。Taro 也在第一时间完成了对 React18 的兼容。
React目前存在两种工作模式: legacy 和 concurrent 。在 concurrent 模式下,会使用 New Client api 来渲染组件。
默认情况下,Taro react 仍会在 legacy 模式下运行。简单修改 @tarojs/plugin-framework-react 插件的配置即可启用 concurrent 模式:
/** config/index.js */
const config = {
plugins: [
['@tarojs/plugin-framework-react', { reactMode: 'concurrent' }]
]
}
不要忘记将项目的 react 版本升级到 v18 哦
详细内容请参考discussions
三、支持服务端渲染(SSR)
与 SPA(单页应用程序,Single-Page Application)相比,服务器端渲染(SSR)能带来带来 更快的首屏渲染速度 和 更好的 seo ,因此 SSR 功能是大家期望 Taro 支持的特性之一。
2. 实现原理
Taro 在 3.1 版本提出了 开放式架构 的思想,让开发者可以通过编写插件来让 Taro 支持一个新的平台。
通过 Taro 插件,将 React 生态中知名的 Next.js 框架作为 Taro 的一个新的目标平台,以此让 Taro 能够支持服务端渲染(SSR)。
目前这个插件项目的地址位于: SyMind/tarojs-plugin-platform-nextjs
:warning: 插件目前处于早期建设中,不建议用于生产环境!
3. 安装与使用
安装插件和 Next.js 框架。
# 使用 npm 安装插件与 next.js
npm install tarojs-plugin-platform-nextjs next
# 使用 pnpm 安装插件与 next.js
pnpm install tarojs-plugin-platform-nextjs next
在 Taro 项目的编译配置中添加本插件。
const config = {
plugins: [
'tarojs-plugin-platform-nextjs'
]
}
开始尝试它吧!
npx taro build --type nextjs --watch
四、支持多页应用(MPA)
很多同学通过阅读 Taro 的源码发现,Taro 曾在 1.x 支持过多页面应用,通过配置 multi 模式就可以开启该特性,但是由于并没有很好支持,也没有相应的业务场景测试,最终并没有在文档中呈现。
在 2.x 发布时,由于各种原因我们回滚了该特性,尽管开发者们依旧可以通过插件或者在项目内自定义 webpack 配置实现类似的需求,不过这依旧会在一些细节上难以处理得尽善尽美。比如需要额外配置文件拆分规则避免冗余的代码,对于 MPA 也并不需要 taro-router 提供对于路由相关的事件方法的支持……
MPA 是不少社区开发者所追求的重要特性之一,为此我们改写了 taro-loader 和 taro-router 以适应该模式的个性化需求,应用该模式也只需要如下配置:
module.exports = {
// ...
h5: {
// ...
router: {
mode: 'multi'
}
}
}
需要注意的是,有很多小程序事件和方法都是基于 SPA 模式设计使用的,在 MPA 模式并不适用,所以会存在一些问题,比如由于多页面导致 TabBar 会重复加载,App 级的生命周期会重复触发,不支持路由动画,生产环也需要额外配置路由映射等等,开启该模式前需要认真考量适用场景。
五、RN相关依赖库由 unimodules 升级至 expo
Expo 是 React Native 生态中的重要角色,提供了非常多优秀的模块,在 Taro 中有较为广泛的使用,如 expo-av、expo-camera 等,将来我们还会持续接入新的模块。Expo 的模块系统,由 unimodules 变更为 expo 已有一段时日,其架构变更原因可参考文章: What’s new in Expo modules infrastructure 。
Taro v3.5 及以后将使用新的模块系统,可以通过 taro init 选择 react-native 模板体验。如果你使用的是 Taro 壳工程,可切换到0.67.0-expo 分支体验。
新老版本的 Taro 及壳工程之间混用的话,将存在不兼容情况,主要原因是存在多个版本原生依赖导致,可通过 resolution 进行版本锁定解决,相应版本参考此处。
后续壳的工程将不再包含 unimodules 版本。旧版本升级可参考此PR。
注意:升级为 expo 将不再支持 iOS 11,详细内容请参考discussions。
六、升级指南
1. 安装 v3.5.0-beta 的 CLI 工具:
npm i -g @tarojs/cli@beta
2. 更新项目依赖
如果安装失败或打开项目失败,可以删除 node_modules、yarn.lock、package-lock.json 后重新安装依赖再尝试。
2.1 把 package.json 文件中 Taro 相关依赖的版本修改为 3.5.0@beta
2.2 Breakings
- vue2 项目需要添加 devDenpendencies: "@vue/babel-preset-jsx": "^1.2.4”
- Vue3 项目需要添加 devDenpendencies: "@vue/babel-plugin-jsx": "^1.0.6"
React 项目需要添加 devDenpendencies:
"@pmmmwh/react-refresh-webpack-plugin": "0.5.4", "react-refresh": "0.11.0"
PReact 项目需要添加 devDenpendencies:
"@prefresh/webpack": "^3.2.3", "@prefresh/babel-plugin": "^0.4.1"
2.3 重新安装依赖
3. 使用 Webpack5
新项目在创建项目时,选择编译工具为 "webpack5" 即可。
旧项目升级后需要更新依赖:
- 建议首先删除 node_modules 、 yarn.lock 、 package-lock.json 。
- package.json 中删除 @tarojs/mini-runner 和 @tarojs/webpack-runner 依赖,添加 @tarojs/webpack5-runner 依赖。
- 重新安装依赖。
- Taro 编译配置添加 compiler: 'webpack5' ,最后开启编译。
接下来我们会继续对 v3.5 版本进行迭代,包括实现 H5 的依赖预编译等。而在 v3.6 版本则会落地对 Vite 的支持,同时优化运行时的性能。
最后的最后,衷心各位感谢参与 Taro 开源共建的同学!为了建立更加完善、更加可持续的 Taro 开源生态,突出贡献者价值,Taro 推出了 更清晰的参与机制和荣誉激励机制,欢迎更多的同学参与进来~
作者:凹凸实验室
来自:https://segmentfault.com/a/1190000041871269
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK