美文网首页
Taro 3.5 beta 编译提速,支持 Webpack5、R

Taro 3.5 beta 编译提速,支持 Webpack5、R

作者: 凹凸实验室 | 来源:发表于2022-05-20 11:02 被阅读0次

    编译速度一直是困扰开发者的头等问题,现阶段大型 Taro 项目即使在增加了 cache-loaderthread-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 则无需再对依赖进行编译,从而提升编译速度。

    依赖预编译可以分为三步:

    1. 收集依赖
    2. 打包依赖
    3. 打包 Module Federation Remote 应用

    Taro 参考 Vite 使用了 esbuild 收集用户使用到的第三方依赖,并分别进行打包。打包后的模块会作为 Webpack 的 entry,最终打包为模块联邦 Remote 应用,供主应用(Host)消费。实现细节请参考 RFC 文档

    Taro 会在小程序环境的 dev 模式下默认开启依赖预编译功能。首次编译时,因为使用了 esbuild 打包第三方依赖,所以会比普通编译稍快。二次编译时,Taro 能直接复用 Remote App,Webpack 只需编译业务代码,因此根据不同项目会有不同的编译提速效果。

    依赖预编译的流程图:

    prebundle.png

    3. 提速效果

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

    compile-speed_dev.png compile-speed_prod.png

    可以看出:

    1. 在 dev 环境下因为 Taro 默认开启了依赖预编译,因此 Webpack5 首次编译速度比 Webpack4 稍快。而 prod 环境没有默认开启依赖预编译,因此两者速度相当(而且 Webpack5 需要写入缓存,可能会比 Webpack4 稍慢)。
    2. 无论是 dev 还是 prod 环境,在完全命中缓存的最优情况下,Webpack5 的编译速度都能得到极大提升。即使是修改源码导致了部分缓存失效时,编译速度仍然比首次编译快得多。

    4. 使用

    旧项目升级后需要安装 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目前存在两种工作模式:legacyconcurrent 。在 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)

    1. 动机

    与 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

    ⚠️ 插件目前处于早期建设中,不建议用于生产环境!

    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-loadertaro-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_modulesyarn.lockpackage-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 推出了更清晰的参与机制和荣誉激励机制,欢迎更多的同学参与进来~

    相关文章

      网友评论

          本文标题:Taro 3.5 beta 编译提速,支持 Webpack5、R

          本文链接:https://www.haomeiwen.com/subject/sokfprtx.html