背景
项目本身是vue2全家桶,代码差不多一年前,涉及到的库不是很多,比较标准的后台admin项目
天天看着都说vite好vite快,有的文章甚至达到了开发环境10倍,然后看文章变更的也不多,内心蠢蠢欲动0 0
今年这段时间正好有空,正好也是vite升级到了2代目,脱离了vue3的强依赖,于是尝试下非主流程公司业务从vue-cli迁移到vite
题外
看大家帖子都说多简单,变更的就那么多点,是我们的项目太奇怪了?
在过程中基本是一步一个坑,果然还是自己太菜了TT
迁移过程
1.配置文件与处理vue
配置文件和webpack一样,在根目录下创建 vite.config.ts
npm i -D vite
配置文件长的也很像vue.config
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
// ...
],
})
awesome-vite插件地址
在这边找到vue的对应插件vite-plugin-vue2
npm i -D vite-plugin-vue2
。。。
plugins: [
createVuePlugin({
jsx: true,//这个我感觉没用?还是我的使用方式有问题
}),
],
。。。
Q1:vue插件的这个jsx是怎么生效能处理哪几个问题,看起来是通过babel-preset-jsx?处理的
2.入口与 HTML 文件
这里和webpack有些不同了,vite同样需要入口文件,但是使用的方式是从html进入
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=1024,initial-scale=1.0" />
<title>嘻嘻嘻</title>
</head>
<script>
window.process = {}; //这里解决了path引入报错的问题
</script>
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<!-- built files will be auto injected -->
</body>
</html>
因为原有项目html文件是在public文件架下,而且是多入口,所以配置文件要修改 对应的入口
build: {
rollupOptions: {
input: {
main: path.resolve(__dirname, 'public/index.html')
},
},
}
诶,没想到吧,不行!好奇为什么。虽然最后还是乖乖把主index放到了根目录
Q2:这个问题晚点也要研究下
Q3:window.process = {};不加这个我的path会报错 没有process
3.环境变量
webpack为我们提供了process.env
去访问环境变量,区分各个环境
const PRO_HOST = process.env.PRO === 'xxx'
? 'aaa'
: 'bbb';
vite 仍然支持环境变量的使用,但是提供了另一套import.meta.env
来代替process.env
去访问环境变量:
也提供了根目录下.env
文件去增加额外环境变量
4.替换 CommonJS 以及各种引入问题
1.替换commonJs 这一块是参考掘金另一个老哥的,说白了是require换成import
2.样式引入的替换
@import '~@/styles/mixin.scss';
@import '~@/styles/variables.scss';
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";
直接写成@import '@/styles/variables.scss';
就可以了,不再需要波浪号
$--font-path: 'element-ui/lib/theme-chalk/fonts';
@import "element-ui/packages/theme-chalk/src/index";
3./deep/的支持
vite对css预处理器提供了插件的支持,但是需要安装预处理器。所以原有的sass-loader就不需要了,只需要装个sass的预处理器就可以,安装最新的后发现不支持/deep/
,那就按照最新的::v-deep
走呗。顺带对这个vue专属语法有了根深一层的认识
4.Glob 导入 (在这边遇到很多坑)
说到这,是为了解决路由和store的问题,处于webpack的方便,之前路由的写法是按照文件夹自动导入的,如下代码:
export const basicRoutes = require
.context('@/views/basic', true, /\/index\.vue$/)
.keys()
.map(url => url.replace(/^\.\//, '').replace(/\/index\.vue$/, ''))
.map(pathName => {
return {
path: `/${pathName}`,
name: pathName,
component: () =>
import(/* webpackChunkName: "[request]" */ `@/views/basic/${pathName}/index.vue`),
};
});
从webpack切换到vite后,require.context不能再用了,于是看文档找到import.meta.globEager
这个vite提供的导入方案,分为glob和globEager异步和同步两种
依旧是先看代码后说问题
let files = import.meta.globEager('/src/views/division/*/index.vue');
export const divisionRoutes = Object.keys(files)
.map(url =>
url
.replace(/\/index\.vue$/, '')
.replace(/src([a-zA-Z\_]*\/)*/, '')
.replace(/\//, '')//原谅我丑陋的正则
)
.map(pathName => {
return {
path: `/${pathName}`,
name: pathName,
component: files[`/src/views/division/${pathName}/index.vue`].default,
};
});
这里一共遇到了2个问题,应该有更好的解决方案,但是出于先解决问题只是勉强能用
import.meta.globEager('/src/views/division/*/index.vue')
的引入是modules组成的对象,和原来的路径不太一样- 这里component的导入,一开始用的是import导入,然后遇到问题
安装
@rollup/plugin-dynamic-import-vars
插件后 在
import dynamicImportVars from '@rollup/plugin-dynamic-import-vars';
plugins: [
createVuePlugin({
jsx: true,
}),
injectHtml({
injectData: {
title: '用户管理系统',
},
}),
dynamicImportVars(),
],
结果反而报错。由于报错在vite,于是想着引入的直接是modules,干脆直接引入算了,于是就有了上面的代码,成功解决问题
component: files[`/src/views/division/${pathName}/index.vue`].default,
Q4: 这里的解决方案有待商榷,待学习后尝试解决
5.jsx的问题
vue-cli是自动引入的babel的,所以在里面jsx是可以直接用的,比如下面的代码
vnodes.push(<svg-icon icon-class={icon} />);
但是这在vite当中就不识别了
没有转换成功
开篇提到了引入的vue2插件,发现里面有jsx options
但是打开后没有用 ,可能是我打开方式不对吧
createVuePlugin({
jsx: true,//这个我感觉没用?还是我的使用方式有问题
}),
最后是通过改为createElement方法去解决的
render(h, context) {
const { icon, title } = context.props;
const vnodes = [];
if (icon) {
const elHtml = h('svg-icon', {
attrs: {
'icon-class': icon,
},
});
vnodes.push(elHtml);
}
if (title) {
const elHtml = h(
'span',
{
attrs: {
slot: title,
class: 'system-menu-title',
},
},
title
);
vnodes.push(elHtml);
}
return vnodes;
},
Q5: 晚点试试看通过rollup-plugin-babel
外加@vue/babel-preset-jsx
通过插件的方式支持jsx
6.方法上的装饰器的使用
原有项目为了实现一些控制请求重复提交和其他的一些需求,通过装饰器的方式写了一些方法,用到的时候方法上直接加上就好了
但是在vite中遇到了问题,查了相关资料也改了build.target
发现还是不行,现在只好先注释掉处理其他问题
Q6.装饰器的使用
@debounceDecorator()
async getSearchList() {}
5.alias
话不多说,vite提供的配置,按照要求加上就好
resolve: {
alias: {
'@': path.resolve(__dirname, '/src'),
},
},
7.生产环境
等待更新ing
8.babel plugin
打算下尝试下插件方式解决上面的一些问题
结果
差不多到现在能用了,还有一些样式覆盖的都是小问题了,检查了下基本功能都在,明天着重解决装饰器和jsx的问题
总体来说,使用体验上没啥大的区别,编译速度确实是快了很多, 但是默认的提示语里reload不包含时间,后面加xN代表数量,只有一句话,而且闪动的很快,还不太习惯
初始的编译
对比原来差不多七八秒是快了很多,
浏览器连接时间:
暂时看,嗯,很香0 0,在报错和异常上再挖掘下不是不可以作为生产用