最近给公司采购的老旧的 node8
+ vue2.6
+ webpack3
+ npm
项目做构建优化
背景:整个项目 build
一次 20+ min
,本地冷启动和热更新也忒慢,依赖 npm i
一下也得装个 20+ min
众所周知,Node 版本
,依赖包管理工具
和 构建工具
的升级都能对构建速度的优化有帮助
Node
我先给 node
版本升到了 16.20
,这个版本算是稳定能用 pnpm@8
的版本了,也在公司统一的 node
大版本范围里,解决问题就是把配套的报错的依赖升级到和 node
版本匹配,主要是 sass
, @vue/cli-service
依赖包管理工具
再给 pnpm@8
加上,这里的问题碰见的是项目里有些依赖项之前没有显性安装,导致 package.json
里缺失了,可见旧版本的 npm
确实有点毛病,从 package-lock.json
里逐个查到报错依赖的版本再手动装上就行了
构建工具
对比
项目越大,vite
带来的构建优化增益就越明显,webpack
即使用 esbuild
再开上线程和缓存,在海量项目文件面前,全量构建也是慢的不得了。换上 vite
,开发冷启动的预构建和访问构建慢一些,可比 webpack
快多了,热更新更是秒更,快乐的不得了
vue2.7
这里要解决的问题是 vite
没有直接支持 vue2
版本,但还好找到了 vue2
的支持插件 @vitejs/plugin-vue2
,因为插件好像不支持 2.6
版本,所以一开始找的社区提供的插件有点坑,但后来想大换血干脆换的彻底点,vue3
是不要想了,2.6 => 2.7(latest)
还是可以的,所以连带着把 vue
版本也往上提了提,但一些 vue2.7
被废弃的语法就要改动下了,但还好比较少全局批量换掉检查一遍
兼容
然后就是 vite
没有提供 node-polyfill(vite-plugin-node-polyfills 解决)
,也没有 require(@originjs/vite-plugin-require-context 解决)
还有就是 webpack
里用的是 process.env.xxx
,编译时会从环境变量里找到值填充到逻辑里,而 vite
里没有提供 process
,而通过 vite
配置里 define + loadEnv
也就解决了
动态加载
比较有意思的一个问题是我们有个动态加载页面和组件进行渲染的逻辑:
js
return () => require(path) // path = 'views/x.vue'
vite 里只能替换成以下写法了
js
// { 'views/x.vue': () => import(views/x.vue), 'views/y.vue': () => import(views/y.vue) }
const views = import.meta.glob('@/views/**/**.vue')
// 直接从 views 里找到该页面/组件返回就行
return views[path]
预构建
因为 vite
是增量构建,有时切换页面会碰见数量比较大的依赖文件增量构建,就会导致页面整个自动强制刷新,这对开发带来非常不好的体验,我们比较倾向于无感知的热更新,因此就需要在 vite
构建配置里着重声明 optimizeDeps include
选项,最好把所有让页面强刷的依赖都进行预构建,就可以解决这个问题了