@ys930126
2021-09-29T15:03:36.000000Z
字数 3953
阅读 52
从0到1将一个
Vue3.0
+Vant-UI(v3.x)
项目从Vue-cli迁移到Vite
wp2vite,一个将webpack项目转换为vite项目的工具
对比 | Vue-cli | Vite |
---|---|---|
生态&社区 | 生态完善,历经检验 ✅ | 后起之秀,根基不深 |
- | 问题&解决方案多✅ | 目前社区支持不够丰富 |
- | 插件丰富✅ | 目前插件不够丰富 |
- | - | - |
兼容 | 兼容Vue2✅ | 对Vue3兼容较好,Vue2可能会有问题 |
- | 兼容部分旧版浏览器✅ | 开发环境仅支持现代浏览器(ES6),生产可以根据配置 |
- | 兼容CommonJS ✅ | 不兼容CommonJS |
- | - | - |
开发&构建 | 开发和生产构建方式一致(基于webpack)✅ | 开发和生产构建不一致(开发基于ESM,生产构建基于Rollup) |
- | 开发启动速度慢,HMR全量更新,响应较慢 | 开发启动速度一般,HMR按需更新,响应极快✅ |
- | 开发生成将随着项目内容线性增长,时间复杂度O(n) | 开发生成时间复杂度始终为O(1) ✅ |
- | 基于webpack打包,打包后内容体积偏大 | 对比来说,打包基于Rollup,如使用 tree shake 打包后内容体积可适当缩小✅ |
本次迁移采用该方案
vite.config.js
配置文件并将vue.config.js
配置迁移 [可使用wp2vite工具操作]vite
查看是否正常执行vite build
查看是否正常构建vite preview
查看本地构建运行结果是否正常对比环境采用相同用户在Chrome浏览器无缓存状态下的数据
使用AskBob-ORCP 术康服务包V1.2 ~/holderOrderList
机器环境:Mac os
Chrome版本:V93.0.4577.63
NodeJS: v16.9.1
对比 | Vue-cli | Vite | 备注 |
---|---|---|---|
开发环境 | - | - | - |
服务启动时长 | 25000ms±10000ms | 700ms±100ms | 速度提升20~35倍 |
HMR(热更新)时间 | 800±100ms | 20ms± | 几乎保存即生效 |
首次页面请求数(All) | 17 | 412 | Vite开发环境不打包直接import依赖,会导致页面请求内容较多,如css多级依赖 |
请求内容Size | 7MB | 5.6MB | Vite 开发按需加载,无打包,内容较少 |
总耗时 | 1.98ms | 1.92ms | 总耗时会有闪动,基本持平 |
生产环境(模式es2015) | - | - | - |
产物大小 | 6MB | 2.9MB | 包大小减少50% |
首次页面请求数(All) | 19 | 16 | |
页面内容Size | 1.3MB | 581K | 页面内容减少60% |
首次打开页面时间 | 5.04s | 725ms | 首次页面打开时间提升7倍 |
Vite 构建使用ESM,不支持CommonJS语法
所以需要将引用包方式从
const r = require('package_name')
修改为import pageage from 'package_name'
入口文件可配置,默认路径由/public
改为 /
官方说明
Vue-cli 入口文件为
~/public
但是 Vite的路径可在vite.config.js
中配置root属性
,默认为process.cwd()
。所以需要将原/public
下的文件迁移到/
根目录,或者roo改为/public
环境变量使用变更,从 process.env
换成 import.meta.env
在一些js中可能会使用到环境变量进行判断,如
process.env.NODE_ENV
在Vite中需要修改为import.meta.env.MODE
,在index.html入口文件中,如果使用了ejs
语法,此时无法通过import.meta.env
拿到环境变量。详见下方坑&填坑/②
对CDN支持不友好,建议使用 npm 安装后 import 引入
在迁移时遇到问题,在使用cdn时, 组件无法正常工作,报错
TypeError: ParentNode is undefined
,改为 import 后正常。
涉及到vue
、vuex
、vue-router
最下方有一些好心网友经验文档,建议按需查阅
① index.html中ejs代码段未工作
vue-cli
默认使用html-webpack-plugin
解释/public/index.html
中的ejs模板语法,且开箱即用不需要自行再引入该包。vue-cli静态html说明
vite
需要支持入口文件中的ejs语法,需要在vite.config.js
配置文件中引入插件vite-plugin-html
来进行工作 。
② index.html中的process.env
与import.meta.env
无法正常工作
1.Vite环境变量暴露变更,由
process.env
更改为import.meta.env
2.Vite 不支持index.html文件中使用import.meta.env
3.需要通过在vite.config.js中使用define
配置,注入常量。官方文档
4.Vite 暴露的环境变量需要符合envPrefix
前缀,注意配置,默认为VITE_
// 为保证导入正确,请务必注意配置中和loadEnv()入参中的envDir和 envPrefix保持一致
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(mode=>{
const envDir = 'env'
const envPrefix = 'VITE_'
const env = loadEnv(mode,envDir,envPrefix)
return {
define:{env},
envDir,
envPrefix
}
})
③ path配置 import 等路径别名,如@
和vue-cli中使用webpack的resolve.alias一样,vite也使用相同的方式用于路径别名设置。配置方式如下
resolve:{
alias:{
"@":path.resolve(__dirname,"./src")
}
}
④ jsonwebtoken包在运行和构建时有异常错误
1.报错 property process is undefined。
原因在jsonwebtoken中有判断process.version Nodejs版本,但是在运行时,已经没有了process环境变量。
2.报错 package emitter is not found .
原因未知
解决方案:
原来是全量引入
jsonwebtoken
,但是项目中仅仅使用了jsonwebtoken的decode方法
删除引用jsonwebtoken
改为引用jwt-decode
,且将对应调用方式调整
⑤ svg图生成icon组件,require is undefined
之前通过reqire.context(path,true,patter)动态引入全部svg现在只需要通过
import.meta.globEager(patterRule)
即可动态引入全部svg
import SvgComponent from '/path'
import Vue from 'vue'
export default {
Vue.component(SvgComponent);
// 原引入方式
const requireAll = reqContext =>reqContext.keys().map(requireContext);
const req = request.context('./assets/svg',true,/\.svg$/);
requireAlll(req);
// 新引入方式
import.meta.gloEager('./asstes/svg/*.svg')
const water_levels = [];
for (let [key, val] of Object.entries(modules)) {
water_levels.push(val.default);
}
}
⑥ 文件缺失后缀导致import报错
原vue-cli默认支持忽略后缀
.vue
,而Vite要求vue文件引入时确定后缀名。但是可以通过配置模糊匹配后缀。文档
resolve:{
extensions:['.vue','.js']
}
⑦ Vite内联插件报错
需要引入插件
@vitejs/plugin-vue
Vite插件
⑧ 部分样式异常
1.在less,使用了这样的 url('~@/path') 语法,搜索替换 将 ~@ 替换为 @ 就可以了
2.前端组件引用vantUI(v3.x)组件库,该组件库按需使用需要引用vite-plugin-style-import插件,可参考vant官方文档#方式二. 在 Vite 项目中按需引入组件