前言

早在Taro3.5的版本发布时,Taro团队就表示将会在接下来的3.6版本落地对Vite的支持。

Taro4.0支持使用Vite构建_H5

但在3.6的版本中根本就没看到Vite的身影,随着社区对Vite的呼声越来越高,终于在Taro4.0beta版本中支持了这一功能!

目前 Taro 在 Vite 编译系统适配方面,优先支持了小程序、H5 和鸿蒙三端。

但仔细一想🤔,H5支持使用Vite编译可以理解,但小程序是只支持CommonJS模块化规范并且不支持从不支持从网络中加载 JS 资源,而Vite的优势是在于它基于ESM的模块化规范从而实现的no-bundle,极大地提升了前端项目的构建性能。

这么看来,Vite在本地开发时直接利用ESM实现的无打包(no-bundle)构建优势,在小程序开发中难以直接发挥。那么Taro团队又是如何处理的呢?

体验

由于该功能还处于测试阶段,所以我们现有的脚手架还暂时不能初始化vite版本的taro项目,需要安装4.0版本的脚手架工具

安装脚手架

npm i -g @tarojs/cli@beta

⚠️需要注意的是:从4.0版本开始,将 Node.js v18 设置为长期支持的最低 node 版本

创建项目

taro init taro_project

也可以跳过安装 CLI 工具使用 npx 创建项目

npx @tarojs/cli@beta init taro_project

Taro4.0支持使用Vite构建_H5_02

运行项目

接着我们来把项目运行起来看看与之前的webpack构建的有何不同

Taro4.0支持使用Vite构建_Taro_03

Taro4.0支持使用Vite构建_加载_04

项目虽然是成功跑起来了,但感觉跟自己想象中的不太一样呀?

  • 启动速度并没有想象中的那么快
  • 编译产物看着跟webpack差不多,引以为傲的no_bundle呢?
  • 怎么还是CommonJS,看来还是绕不开小程序的限制

对于Vite的支持Taro4到底做了什么?

在Taro的rfc中有着关于Vite的记录:

Taro4.0支持使用Vite构建_加载_05

那说白了Taro支持Vite最大的收益者是H5而不是小程序,看到这里估计很多人都会失望了,大家使用Taro的重心应该是在小程序而不是H5吧。

H5编译逻辑

为了兼容 Taro H5 的编译,只需要实现:编译配置对齐、设置编译 Entry、注入运行时代码。其余的工作交给浏览器和 Vite 处理,开发者就能拥有快速的项目启动和更新体验。

3.1 编译配置对齐

Taro H5 主要使用了 Webpack 的 Resolve 配置,如 aliasmainFields 等,这些配置在 Vite 中都能找到对应。

3.2 设置编译 Entry

对于Vite来说,开发环境下index.html就是项目的入口文件,我们可以使用 Vite 插件的 transformIndexHtml 钩子在 index.html 中注入对 app.config 的引用:

<script type="module" src="./app.config.js"></script>

3.3 注入运行时代码

目前 Taro H5 使用了自定义的 Webpack Loader 去注入运行时代码,从而实现页面加载、组件渲染等功能。在 Vite 中可以使用 Vite 插件的 load 钩子达到同样的目的。

小程序编译逻辑

由于小程序不支持从网络中加载 JS 资源,只能使用 Vite 的 lib 模式进行打包,输出小程序规范下的四种产物:js xml css json

与H5 一样,使用 app.config 作为 Entry,输出产物则使用小程序支持的 CommonJS 格式:

{
  "build": {
    "lib": {
      "entry": "./app.config.js",
      "formats": ["cjs"],
      "fileName": "app.js"
    }
  }
}

现在真相大白了吧,小程序只是使用了Vitelib模式进行打包,那这跟直接使用rollup也没啥区别😂

总结

从目前的版本来看,Taro支持使用Vite构建最大的受益者是H5而不是小程序,对于小程序的编译也并不会快多少,从原理上看,现在想要使用Vite的核心功能似乎走不通,除非你能让小程序作出改变,让小程序支持从网络中加载JS资源,但估计也不太可能,毕竟这一限制是出于安全考虑。

所以想要提升本地构建速度,可以考虑下这个方案:减少单次构建构建目标,具体操作可以参考之前写的这篇文章:如何提升项目的本地构建效率?

Taro4.0正式版预计会在今年的Q2阶段发布,到时候再看看会不会有惊喜吧!