开发环境升级 Vite 踩坑总结
为什么选择迁移 vite
最主要原因就是本地开发启动速度快。在使用 vite 之前,特地先使用了 speed-measure-webpack-plugin 这个插件来检测 webpack 的打包速度,结果是需要 15s - 20s。 相比之下,在切换 vite 之后,几乎就是秒启动

当然也有一个弊端:开发环境的首屏渲染、懒加载相比 webpack 更慢了,根本原因是 vite 把源文件的 resolve、load、transform、parse 延后到由浏览器执行。但只要在首屏渲染完成后,vite 会使用强缓存对构建内容进行缓存,在这之后相比于 webpack 每次更新内容之后的重新打包,vite 的热更新又是是丝滑的热更新体验
为什么开发环境不一并迁移 vite?最主要的考虑还是担心影响现有业务流程,而且 vite 的生产环境也是通过 rollup 打包来实现的,在生产构建没有很大的性能时间问题前暂时还是使用 webpack 进行生产打包构建
迁移步骤和踩坑总结
首先是安装依赖,因为最新版本的 Vite 3.0 支持的 Node 最低版本是 14.18+,不再支持 Node 12,考虑到老项目,还是选择了 Vite 2.9 版本。另外老项目使用的还是 Vue2,所以需要使用到 vite-plugin-vue2 插件,让 Vue2 项目中可以使用 Vite
- 安装依赖:npm i -D vite@^2.9.14 vite-plugin-vue2,然后在package.json新增一个启动命令,新建一个vite.config.js配置文件
1// vite 启动命令
2"scripts": {
3  "dev:vite": "vite",
4},
5
6// 新增 vite.config.js 文件和基础内容
7import { defineConfig } from "vite";
8import { createVuePlugin } from "vite-plugin-vue2";
9
10export default defineConfig({
11  plugins: [
12    createVuePlugin({
13      jsx: true,
14    }),
15  ],
16});不出意外的话是可以直接启动的,但是页面是空白,原因是因为在传统的 vue-cli / webpack 项目中 index.html 文件一般都是放在 public 目录下。而在 vite 项目中 index.html 是放在根目录下,作为整个项目的入口,通过 index.html 中的 <script> 标签来加载 js 文件。考虑到升级前定下的原则:尽量不改动原有项目代码和配置,所以需要使用到 vite-plugin-html 这个插件修改 vite 识别 index.html 目录的位置
- 安装依赖 npm i -D vite-plugin-html,然后在vite.config.js中配置index.html入口
- index.html 新增:<script type="module" src="/src/main.js"></script>
1import { createHtmlPlugin } from 'vite-plugin-html'
2
3export default defineConfig({
4  plugins: [
5    createHtmlPlugin({
6      template: 'public/index.html',
7      minify: true,
8    }),
9  ],
10})接下来启动项目,会发现 Vite 无法识别忽略 .vue 后缀的文件,这是因为 Vite 已不再默认忽略.vue 扩展名(根据 github 上 issue 讨论,尤大回答设计就是如此),所以只能手动兼容

- 在 vite.config.js中手动配置后缀名忽略选项
1export default defineConfig({
2  resolve: {
3    // 手动配置后缀名忽略选项
4    extensions: ['.vue', '.js', '.json', '.mjs'],
5  },
6})继续启动项目,提示找不到 sass 依赖,只能重新安装 sass,版本选择低一些,sass@~1.26.5,过高可能存在问题
- 安装 sass 依赖:npm i -D sass@~1.26.5

接下来启动项目需要解决两个别名识别问题,一个是常用的 webpack 别名定义,一般都会在 webpack 配置文件定义 src 目录的别名方便开发引入文件。第二个是 sass 别名的引入,项目中引入 sass 文件的方式是 @import '~variable.scss',vite 支持了 @import 的引入,但是无法识别~ 别名

- 增加适配 webpack 定义别名 @xxx和@/xxx的场景
- 增加适配引入 sass 文件 ~/xxxx和~xxx的场景
1export default defineConfig({
2  resolve: {
3    alias: [
4      // 适配 @xxxx、@/xxxx
5      { find: '@', replacement: path.join(__dirname, 'src') },
6      // 适配 ~/xxxx
7      {
8        find: /* ~/ */ /^~(?=\/)/,
9        replacement: path.join(__dirname, 'node_modules'),
10      },
11      // 适配 ~xxxx
12      {
13        find: /* ~ */ /^~(?!\/)/,
14        replacement: path.join(__dirname, 'node_modules/'),
15      },
16    ],
17  },
18})继续填坑,提示 require is not defined,由于开发环境使用浏览器的 ESM 模式,不支持 CJS 模式,本着不修改源码的原则,继续使用插件兼容 CJS 的模式
- 安装 @originjs/vite-plugin-require-context 和 vite-plugin-commonjs 插件并在 vite.config.js文件中引入
1import commonjs from 'vite-plugin-commonjs'
2import ViteRequireContext from '@originjs/vite-plugin-require-context'
3
4export default defineConfig({
5  plugins: [
6    // 兼容 commonjs
7    commonjs(),
8    // 兼容 webpack require.context 写法
9    ViteRequireContext(),
10  ],
11})在 webpack 中使用环境变量的方式主要是通过 process.env.xxx,而 vite 中是通过 import.meta.env.VITE_xxx 的方式访问环境变量,为了不影响生产环境 webpack 环境变量的使用,需要自定义项目中使用到的环境变量
- 在 vite.config.js中自定义项目使用到的环境变量
1define: {
2    // 同 webpack.DefinePlugin,手动兼容 dev 环境 process.env
3    'process.env': {
4      VUE_APP_ENV: 'development',
5      VUE_APP_REQUESTPATH: '/hrpb',
6      VUE_APP_TITLE: '传统金融业务人员PB系统',
7      VUE_APP_SHORT_TITLE: 'hrpb'
8    }
9},到这里项目中基本可以正常启动不报错了,但是如果项目使用的 UI 组件库是按需引入的话,还要在 vite 中重新配置一遍按需引入
- 使用 vite-plugin-style-import 配置 UI 组件库按需引入
- vite.config.js配置 ant-design-vue 主题色等自定义颜色
1import { createStyleImportPlugin, AndDesignVueResolve } from 'vite-plugin-style-import'
2
3plugins: [
4  // 导入 ant-design-vue 样式
5  createStyleImportPlugin({
6    resolves: [AndDesignVueResolve()]
7  })
8],
9css: {
10  // 定义 ant-design-vue 颜色
11  preprocessorOptions: {
12    less: {
13      modifyVars: {
14        'primary-color': '#b60005'
15      },
16        javascriptEnabled: true
17    }
18  }
19}迁移 vite 后效果
冷启动时间直线减少,现在只需要 2 秒左右,而且即使项目体积增大,启动速度也没有太大的变化,其次就是热更新几乎是无感的,不像 webpack 可能还需要等待一两秒的重新打包

但现在 vite 的首屏加载时间确实是存在的一个问题,相信这也是 vite 后续提升的方向之一吧
