
我工作不饱和(误),所以找点事做,俗称没事找事~
其实是早有预谋,选在这个时机是我怕以后没机会了
该项目是基于vue-cli创建的webpack-vue2的开发环境,package.json配置如下:
由于代码是公司的资产,所以这里简单的说下配置(vue.config.js + babel.config.js):
src,生产环境得是mindevServer代理部分接口css.loaderOptions.postcss的autoprefixer兼容csscss.less,覆盖组件库lib_b定义的主题色变量(lib_b是用less预处理样式)aliasts文件,所以使用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.contextmust 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环境问题。