最终鼓起勇气把公司五年的webpack老项目改成了vite

语言: CN / TW / HK

theme: awesome-green

一.【 升级原因 】

工程现状:

1. 项目较早 + 代码量大 + 插件类库版本低 + 各个节点优化空间逐渐变小

2. 为接下来Pro工程瘦身做准备;

造成的困扰:

PS:在以上问题的基础上,webpack已经变得非常不好用了

开发环境服务的不稳定性,严重影响开发效率和心情;

打包后输出文件过大,导致运行环境速度慢、系统性能低;

改造目标:

1. webpack 升级 为 vite;

2. node版本调整;

3. sass 版本升级;

二.【 改造思路 】

版本库描述:

1. 整体保持[email protected]核心基础库不动

2. 使用[email protected]替换[email protected]

3. NodeJs版本v14.19.1升级到v18.7.0(后因版本过高,降回原版本v14.19.1)

4. Npm版本v6.14.16升级到v8.15.0

5. 升级[email protected][email protected](后因版本过高,降回原版本v4.7.2)

6. 使用[email protected]

7. 升级[email protected][email protected]

8. 引用[email protected]使vue2支持vite

思路描述:

按需调整和配置,修改编译环境和运行环境的错误,最终经过测试阶段,代码推送线上

分支保全方案:

origin/dev    dev环境源代码

origin/propre2  pre环境源代码

origin/pro    线上环境源代码

origin/config_vite_nyz_221108  vite配置测试分支

origin/config_webpack_backup_nyz_221109  webpack配置备份分支(拉取自pro分支)

三.【 升级报告 】

| 类目 | webpack(升级前) | vite(升级后) | | --------- | ------------ | ---------- | | 本地服务启动时长 | 230 秒 | 3 秒 | | 修改后热更新时长 | 23 秒 | 1 秒 | | 本地服务性能 | 更新慢 & 服务经常崩溃 | 更新快 & 服务稳定 | | 执行打包任务时长 | 300秒 | 55 秒 | | 打包后输出文件大小 | 37.0 MB | 19.8 MB | | 打包后输出文件个数 | 1372 个 | 787 个 | | 依赖包优化后个数 | 103 个 | 82 个 | | 运行环境兼容性验证 | -- | -- |

四.【 执行过程 】
  1. 初始化一个vite项目

// 注意:这里vite的版本采用2.8.0的,最新的版本创建后续会出现问题 // 要选择vanilla原生项目 , 因为选择vue会默认走vue3,造成与当前版本不匹配 npm init [email protected]

  1. 将原项目的src文件夹和其他用到的文件/文件夹移入新项目
  1. 合并package.json的依赖项,script命令抛弃webpack,保留vite的两条指令

"scripts": { "serve": "cross-env NODE_ENV=development vite", "build": "cross-env NODE_ENV=production vite build" },

  1. 删除外层初始化的main.js,移入或保留原项目的main.js到src下
  1. index.html修改入口引入方式

    <script type="module" src="src/main.js"></script>

  1. main.js修改根的挂载方式

    ``` // // 原代码 // new Vue({ // el: '#app', // router, // store, // render: h => h(App) // })

    // 目标代码 new Vue({ router, store, render: h => h(App) }).$mount('#app') ```

  1. 使用cnpm快速下载相关依赖包

    cnpm install

  1. NodeJs版本不一致,导致[node-sass]找不到并报错,直接拉取latest版本

    cnpm install --save-dev sass sass-loader node-sass

  1. 启动本地服务报错:require is not defined

    原因:vite默认使用es6标准的 import 的导入方式,不支持require引入

    // 下载 cnpm install vite-plugin-require-transform

    // vite.config.js 引入 import requireTransform from 'vite-plugin-require-transform' // vite.config.js 使用 defineConfig({ plugins: [ createVuePlugin(), requireTransform({ fileRegex: /.vue$|.js$|.json$|.ts$|.tsx$/ }) ] })

  1. 服务编译的时候,头部注释信息报错 , 如下图,

    原因:语法编译不通过

    解决:涉及文件较多,全部找出来注掉就可以了

  1. 编译报错:Failed to fetch dynamically imported module

    原因:vue文件引入错误,构建过程无法补全文件后缀并读取

    解决:把vue和js相关引入代码全部加上后缀 ( 涉及代码较多,找出来全部改掉 )

  1. 样式的deep语法报错,找出来全部替换掉

    /deep/ 替换为 ::v-deep

  1. 编译报错:process is not defined

    // vite.config.js define: { 'process.env': {} }

  1. 项目中使用的环境变量报错

    解决:webpack升级vite后,需要创建环境变量文件并使用vite的环境变量

    process.env // webpack import.meta.env // vite

  1. 编译报错:Module “path” has been externalized for brower compatibility and cannot be accesed in client code

    原因:path模块无法在客户端代码中使用 , webpack自动帮我们处理了node内置模块 , vite没有

    解决:安装 path-browserify 代替 path 模块

    cnpm install path-browserify

    import path from 'path' 改为 import path from 'path-browserify'

  1. require兼容配置,某些三方包中的require语法,在开发环境正常,打包环境报错

    // vite.config.js build:{ commonjsOptions: { transformMixedEsModules: true } }

  1. 打包报错:[commonjs] Identifier '_vite_plugin_require_transform_Component' has already

    原因:错误所指的意思是echarts 库中声明的变量已存在,还有再声明的必要吗?

    解决:实则该变量并没有重复声明,所以改动CDN引入的方案,并删掉页面import引入语句

    注意:CDN要引入对应的版本

    jsdelivr相关库文件的CDN地址:https://www.jsdelivr.com/package/npm/echarts

    // echart主入口和单独引入的功能 改为cdn引入 // index.html 引入以下代码 <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/[email protected]/map/js/china.js"></script>

  1. 打包报错:'default' is not exported by node_modules/[email protected]@core-js

    解决:rollup本身是不支持CommonJS的,使用了这个插件,就可以解析CommonJS模块了

    rollup.js相关配置资料:https://rollupjs.org/guide/en/#outputentryfilenames

    cnpm install @rollup/plugin-commonjs -D

    // vite.config.js import commonjs from '@rollup/plugin-commonjs'; plugins: [ commonjs() ]

  1. 打包报错:Error: 'default' is not exported by node_modules/[email protected]

    原因:该代码中的防抖节流方法没有默认抛出

    解决:使用自定义封装方法或工具库平替即可

  1. 打包成功后部署至测试环境:Uncaught TypeError: Illegal invocation,报错如下图

    原因:查看报错位置,可能是因为代码编译转换过程产生的错误

    解决:故调整库版本和引入方式

    ``` 1. es6-promise 引入方式调整

    // require引入方式去掉 require('es6-promise').polyfill()

    改为

    // index.html 引入