用 vite 2 平滑升级 vue 2 + webpack 项目实战
目录
Vite vs. Webpack
完整迁移实战
Vite vs. Webpack
指标对比
经过实际运行,在同一项目中、采用几乎相同的设置,结果如下:
开发环节区别
webpack:
先转译打包,然后启动 dev server
热更新时,把改动过模块的相关依赖模块全部编译一次
vite:
对于不会变动的第三方依赖,采用编译速度更快的 go 编写的 esbuild 预构建
对于 js/jsx/css 等源码,转译为原生 ES Module(ESM)
利用了现代浏览器支持 ESM,会自动向依赖的 Module 发出请求的特性
直接启动 dev server (不需要打包),对请求的模块按需实时编译
热更新时,仅让浏览器重新请求改动过的模块
目前由 webpack 或 vite 做的这些架设本地服务、静态资源打包、动态更新的工作,起码追溯到十多年前陆续都有各种解决方案了
构建环节
考虑到加载和缓存等,在生产环境中发布未打包的 ESM 仍然效率低下
vite 利用成熟的 Rollup,完成 tree-shaking、懒加载和 chunk 分割等
源码浅析
运行 vite 命令后:
1. vite (dev 模式)
浏览器中响应 hmr 的部分:
2. vite build
迁移实践
业务背景和迁移原则
迁移背景:
现有项目的 webpack 开发调试和打包速度已经较慢
查看后台统计数据,项目的浏览器覆盖情况可以支持抛掉历史包袱
项目具有代表性,已经包含了 TS/JSX/FC 等写法的组件和模块
需要渐进迈向 vue3 技术栈
升级原则:
对原有开发打包流程无痛、交付产出物结构基本不变
保证线上产品安全,设置观察期并 兼容 webpack 流程 而非直接替换
覆盖后台访问记录中的主流浏览器并周知测试产品等研发环节
主要涉及文件:
/index.html
-- 新的入口,原有src/index.html
暂时保留/vite.config.js
-- vite 工具的配置文件
vite 版本:
vite v2.8.2
node 版本:
node v14.19.0
实践表明 v14 可以兼顾新的 vite 和既有 webpack 两套流程
如果涉及 jenkins 等部署环节,可能需要关心相关 node 软件包的升级
package.json
依赖
npm scripts
之前的 webpack 命令加前缀(如:"webpack:build"),继续可用
node-sass
升级版本,同时满足了 webpack/vite 的打包要求
index.html
位于根目录,vite 默认的入口
加入
type="module"
的入口文件 script 元素<%= =>
语法变为<%- ->
基础配置
复用并完善了之前的打包和开发配置文件:
vite.config.js 基本结构
resolve 的迁移
之前 webpack 中的配置:
vite 中的写法:
以上最后两项配置属于之前引用的错误路径,vite 无法跳过,并将引起打包失败;需要修正引用或在此特殊处理
build 的迁移
之前 webpack 中的配置:
vite 中的写法:
直接拷贝的素材
业务中有一部分动态路径的素材图引用
<img :src="path">
,path 可能为assets/imgs/noData.png
这样的相对路径webpack 中用 'copy-webpack-plugin' 插件拷贝图片到发布目录下,调试过程中是可以访问到的
vite 用拷贝插件 'rollup-plugin-copy' 同样可以拷贝成功,但调试进程中访问不了 dist 目录
特殊的外部引用
vite 需要用 'vite-plugin-html' 插件来达成和兼容与 'html-webpack-plugin' 一样的 html 注入效果
形如 '/public/v3/css/nav-common.css' 这样的特殊引用,不符合 vite 内部的保留策略,会被删除原
<link>
标签并转换成 js import,这将造成页面无法正常访问结合自定义插件实现打包过程中的 hack 和打包结束后的恢复
传统浏览器兼容
vite 用
@vitejs/plugin-legacy
插件为打包后的文件提供传统浏览器兼容性支持legacy 对 build 速度影响较大,酌情采用
legecy 后全局 css 失效
vue 2 中,
build.cssCodeSplit: false
加上 legecy 将导致全局样式丢失等问题(gitee.com/ZhongBangKeJi)
环境变量
process.env
的写法在 vite 中改为了import.meta
,并且使用上有差异
require.ensure
暂时没有很好的兼容写法,应尽量避免
new Set()
如果使用了 Map/Set 等 ES6 的类型且没有使用 polyfill,应该注意其行为
比如 Set 的值可能在 webpack/babel 的转写中会自动变为数组,而新的流程中需要手动用
Array.from()
处理
总结
webpack 工作流基本可以被 vite 完整复刻,适应线上平滑升级
基于浏览器访问记录评估,大部分项目可以享受 vite 极速打包福利
对于需要兼容 IE 11 等特殊情况的,需要充分测试后,考虑用 legecy 模式迁移
需要注意生产环境 rollup 打包与开发环境的代码会不一致,最好用 preview 验证
最后
如果你觉得此文对你有一丁点帮助,点个赞。或者可以加入我的开发交流群:1025263163 相互学习,我们会有专业的技术答疑解惑
如果你觉得这篇文章对你有点用的话,麻烦请给我们的开源项目点点 star:http://github.crmeb.net/u/defu不胜感激 !
PHP 学习手册:https://doc.crmeb.com
技术交流论坛:https://q.crmeb.com
评论