我工作不饱和(误),所以找点事做,俗称没事找事~
其实是早有预谋,选在这个时机是我怕以后没机会了
该项目是基于vue-cli
创建的webpack-vue2
的开发环境,package.json
配置如下:
由于代码是公司的资产,所以这里简单的说下配置(vue.config.js
+ babel.config.js
):
src
,生产环境得是min
devServer
代理部分接口css.loaderOptions.postcss
的autoprefixer
兼容css
css.less
,覆盖组件库lib_b
定义的主题色变量(lib_b是用less预处理样式)alias
ts
文件,所以使用babel-loader + @babel/preset-typescript处理pages
,多页面应用transpileDependencies
帮忙处理一些自行封装的第三方库vue-cli
绑定的babel-preset
版本这里还是贴demo
代码,避免大家仅看文字看不太明白:
vue.config.js
:
babel.config.js
:
ok,基本就介绍到这里,下面开始我们的改造流程。
注意:此时的nodejs
版本切换至v18.8.0
vitejs/vite-plugin-vue2: Vite plugin for Vue 2.7 (github.com)
因为我们的vue
是2.6.14
,所以我们不能用@vitejs/plugin-vue,又因为我们只能使用vite-plugin-vue2
因为我们只能使用vite-plugin-vue2
,而这个依赖仅支持vite5以下的环境,所以这里选择vite4.5.3
。
注意此时node
版本至少要v18
这个包对标html-webpack-plugin
,主要用来实现多页面 + 动态模板
因为项目中大量使用了webpack
的require
,要手动改挺累的,所以找了这个包用来支持这种写法。
由于生产环境机子nodejs
版本过低,所以连带着本机也只能在这个版本上下徘徊,对于sass
处理器也只能使用node-sass
,这货有多坑爹,相信大家都清楚。
因为要用vite4
的要求之一就是nodejs
版本要高于18
,所以这货是肯定不能用了,自然需要平替。
这里采用dart-sass
和sass
用来平替。
首先我们先去到package.json
中,新增指令:
IS_VITE
环境变量用来区分当前是什么环境。注意你一定要同步这个配置项到vue.config.js
中的全局变量注册IS_VITE: false
,因为生产环境还是使用的webpack
编译,如果少了这个变量就会直接报错卡住。找好依赖并安装之后,我们开始配置vite.config.js
说一下里面的一些点:
html-webpack-plugin
注入的模板数据,现在我们使用vite-plugin-html
里的injectOptions.data
注入,每个key
对应html文件中的<%- key %>
。define
:这里用来定义业务代码中要用到的环境变量,比如我们等会要用IS_VITE
区分部分业务代码(登录跳转逻辑)less
配置注意去掉了lessOptions
的外层optimizeDeps
:exclude
对应前面的externals
,include
对应前面的transpileDependencies
。'~': resolve(NODE_PATH),'~@': resolve(NODE_PATH),
:alias
中多了这俩玩意儿,因为代码中存在一些样式文件是这样引入的:@import url('~@/styles/xxx.src.css')
,所以需要额外再补充。proxy
的规则,vite
中proxy
是基于http-proxy
封装的,它里面的选项可见:https://github.com/http-party/node-http-proxy#options。和之前`vue.config.js`中的写法差不多,但是`router`变成`target`,`pathRewrite`变成`rewrite function`。babel
:你可以看到我这没有再配置babel
,因为vite
自带了babel
,包括对ts
的处理,所以我们并不需要额外引入。然后是babel.config.js
,由于我们是vite
环境,所以不能使用@vue/cli-plugin-babel/preset
,我们直接基于环境变量IS_VITE
区别即可。
另外别忘了在你的.eslintrc
中将IS_VITE
定义为全局变量
这么配置就完成了,然后来说一些兼容性的问题。
虽然我们用了vite-plugin-require
作为替代,但该插件并不是完全支持webpack require
的写法,比如:
需要调整为:
另外如果传入一个变量是绝对不行的(包括webpack require
),比如:
因为require.context
实际上是创建一个执行上下文,执行时再去找,如果传入一个变量,压根找不到。
The arguments passed to
require.context
must be literals!
之前有些不规范写法,将js
命名和vue
文件命名写成一样的,比如:
然后在B
中引入时不带后缀:
这种是webpack
可行但vite不行的操作。因为webpack
底层做了额外操作用来试错,而vite
讲究的是原生
。
业务代码中存在module.exports
的导出方式,改成export default
即可,webpack
自身也支持这种写法。
为啥要这么做,因为vite
把index.html
视作是源码
,所以默认情况下会去找根文件夹里的index.html
,整个服务器也是基于根目录。
当然,这不是不可以调整的。然而我们用了vite-plugin-html,这玩意儿bug还挺多,作者也没空改。。。。所以在经过一些列无意义调整后,还是采用重写public
里的index.html
和preview.html
为_index.html
以及_preview.html
。
同时在根目录里新增index.html
、preview.html
以及login.html
前面说过项目中有俩vue
,一个是node_modules
里的,另一个是public/lib
里通过script
引入的。因为我们配置了externals
,所以生产环境是使用lib
下的,不过我发现在开发环境下,原来的配置也是用的lib
下的,也就是node_modules
里的vue
压根没用上。
但是到了vite
里,我发现它被导入了,也就是说vite
先找的node_modules
里的而不是script
的。
因此原本代码中存在import Vue from 'vue'
的写法就都需要去掉,为什么呢?因为lib_c
也是要用到这个script
版本的vue
,然后往Vue.prototype
里注入了一些内容。而业务代码中又有用到这玩意儿,所以如果不去掉就会导致找不到global vue prototype
里被注入的内容。
原来多页面配置是基于vue-cli
提供的配置项来配置的,貌似会被整合到路由里。但是通过vite-plugin-html
的不行,所以我们需要调整原来的逻辑,这里采用前面全局注入IS_VITE
区分
不过跳回index.html
倒是不需要改,因为访问路径没有index.html
也会跳到那里去。
当前有一个无法解决的问题:生产环境node版本太低,连带着sass
预处理器的依赖也只能是node-sass
。
也是因为这个问题,我们不能光明正大
的添加vite
依赖。
以这也导致当前接入实际开发变得有些儿戏,一旦注入了vite,也就意味着得删掉node-sass
,一旦删掉node-sass
,你的package.json
就不能提交到本地了,会直接让生产环境编译失败。
那要怎么办呢?
package.json
和lock
文件v18
,注入vite
依赖,移除node-sass
,添加dart-sass
,也做备份package.json
和lock
文件,切换node
版本,然后更新提交到本地难顶
这里推荐开本机分支,平时业务代码可以在vite分支里编写,提交时合并即可(反正一般改动较大的需求也都是开分支,相信大家轻车熟路)。
一旦涉及到依赖更新,切换到master
分支即可。
分支注意不要有对应的远程分支,本机即可。
但是这个方案需要考验你的git
熟悉度,你不能再像平时那样add .
了。
分支衍生
依旧是开分支,前面操作不变,然后把分支的package.json
和lock
文件都给添加到.gitignore
里,这样你又可以愉快的add .
了。
目前着实没有好的方案。。
本次迁移不难,难的是nodejs
环境问题。