刚从Webpack转Vue3+Vite?老前端说透90%高频踩坑+场景优化+实用技巧
为什么Webpack用得好好的,周围都在转Vue3+Vite?
别着急赶时髦,先搞清楚两者的核心差异——Webpack是“先打包再启动”,Vite是“按需编译+原生ES模块”,这直接决定了开发体验的天差地别。 之前做过一个中大型后台管理系统的测试,Webpack配置了thread-loader、cache-loader这些加速插件,冷启动第一次大概需要7分半,热更新加了个新路由、改了个组件样式?修改路由可能要等1分多钟模块重新解析,样式稍微复杂点也要半分钟跳一跳加载条;换成同项目的Vue3+Vite模板后,冷启动第一次(没有预构建缓存)只需要1分20秒左右,等预构建完常用依赖,第二次往后冷启动直接10秒内!热更新更不用说,不管是改组件逻辑、样式、还是路由配置,几乎都是按下保存键,页面瞬间同步,完全没有卡顿感。 除了快,Vite的原生生态友好也是优势:直接支持TypeScript、Vue单文件组件、CSS预处理器(比如Less/Sass不用配置太多loader),官方提供的create-vue脚手架一键就能生成符合Vue3规范的基础项目,不需要像Webpack那样手动搭半天Vue-loader、babel-loader的架子,对新手太友好了,不过要注意,生产环境Vite还是会用Rollup打包,所以生产构建的速度和Webpack差不多,甚至优化好的话Rollup的Tree Shaking会更彻底,打包体积更小。
新手入门Vue3+Vite,第一步除了npm create vue@latest还要做啥?
npm create vue@latest确实快,但默认模板的配置太“基础款”了,完全满足不了实际开发的需求,刚转的新手一定要先补这几个关键配置,不然接下来肯定踩大坑。 首先是路径别名的配置,Webpack里我们习惯用@代替src根目录,Vite里虽然默认也会生成alias配置,但别只留一个@!可以再加几个常用的:components代替src/components,@views代替src/views,@utils代替src/utils,这样写导入路径的时候既短又清晰,而且后续重构目录结构也不用改一堆import语句,不过这里要注意两个点:一是Vite.config.ts里配置完alias,还要去tsconfig.json(如果选了TypeScript的话)的paths里同步配置,不然TypeScript会报找不到模块的错;二是路径别名的顺序很重要,Vite会按配置的顺序从上到下匹配,所以越具体的别名要放在越上面,比如先配@components/Button再配@components,避免匹配出错。 然后是开发环境和生产环境的变量配置,很多刚转的新手会直接在代码里写死接口地址,比如const API_URL = 'http://localhost:3000',上线的时候还要全局替换,太麻烦了!Vite提供了.env文件的支持,可以分别创建.env.development(开发环境)、.env.production(生产环境)、.env.staging(预发布环境)这三个文件,变量名必须以VITE_开头,不然Vite不会暴露给前端代码,比如在.env.development里写VITE_API_URL=http://localhost:3000,在.env.production里写VITE_API_URL=https://api.example.com,然后在代码里用import.meta.env.VITE_API_URL来获取,打包的时候Vite会自动根据当前环境替换成对应的变量值,这里还有个小技巧,可以在项目根目录创建一个.env.local文件,用来放本地个人的配置,比如接口代理的端口、调试开关等等,.env.local不会被提交到Git仓库,不用担心泄露个人信息。 接下来是接口代理的配置,开发的时候前端和后端通常不在同一个端口,会遇到跨域问题,Webpack里用devServer.proxy,Vite里用server.proxy,配置逻辑差不多,但细节有差异,比如后端接口地址是http://localhost:8080/api/xxx,前端请求的时候用/api前缀,配置的时候可以这么写:server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: (path) => path.replace(/^\/api/, '') } } },这里要注意changeOrigin必须设为true,不然有些后端接口会因为请求头的Origin不对拒绝请求;rewrite参数是可选的,如果后端接口没有/api前缀,就加上rewrite把前缀去掉,如果有就不用加。 最后是构建优化的预配置,虽然生产环境Vite用Rollup,但默认的Rollup配置可能没有做极致的优化,新手可以先加上几个基础的:比如build.rollupOptions.output.manualChunks,把常用的第三方库(比如Vue、Vue Router、Pinia、Axios)单独打包成一个chunk,把UI组件库(比如Element Plus、Ant Design Vue)单独打包成一个chunk,把业务代码按路由或者按模块拆分,这样用户首次加载的时候可以并行加载多个小chunk,减少首屏加载时间;还有build.minify,可以换成terser(默认是esbuild,压缩速度快但压缩率稍微低一点),然后配置terserOptions去掉console.log和debugger,上线的时候更干净;还有build.sourcemap,可以设为false或者'hidden',减少打包体积的同时避免暴露源代码。
刚转Vue3+Vite,这几个高频踩坑你肯定遇到过!
第一个高频踩坑:图片/字体等静态资源的引入方式变了!Webpack里我们可以用require('./assets/logo.png')或者直接在模板里写
,Vite里require是不支持的(因为Vite用原生ES模块,Node.js的CommonJS模块默认不支持在浏览器端运行),那静态资源怎么引入呢?分两种情况:一种是在JavaScript/TypeScript或者Vue单文件组件的script里引入,要用import的方式,比如import logo from './assets/logo.png',然后直接用logo变量(这时候Vite会把静态资源处理成一个URL字符串);另一种是在模板或者CSS里引入,相对路径和绝对路径(以/开头,指向public目录)都可以用,但是要注意,如果用绝对路径的话,静态资源必须放在public目录下,而且public目录下的文件不会被Vite做任何处理,会原封不动地复制到打包后的根目录,还有个小细节,如果静态资源小于4KB(这个阈值可以在vite.config.ts里通过assetsInlineLimit配置),Vite会把它转换成base64编码直接嵌入到代码里,减少HTTP请求次数。
第二个高频踩坑:全局样式的引入方式变了!Webpack里我们可以在main.ts里用require('./assets/styles/global.css')或者在App.vue的style标签里用@import './assets/styles/global.css',Vite里这两种方式其实都可以,但更推荐的是在vite.config.ts里配置css.preprocessorOptions.globalVars或者css.preprocessorOptions.scss.additionalData(如果用Less的话就是less.additionalData),把全局变量、全局混入(Mixin)、全局函数这些自动注入到每个Vue单文件组件的style标签里,不用每次都手动@import,比如用Less的话,可以这么写:css: { preprocessorOptions: { less: { additionalData: @import "@/assets/styles/variables.less"; @import "@/assets/styles/mixins.less"; } } },这里要注意additionalData的最后必须加上分号,不然Less会报错;还有如果全局样式里有重置样式(比如normalize.css),还是推荐在main.ts里用import导入,因为重置样式是全局生效的,不需要注入到每个style标签里。
第三个高频踩坑:Vue2里的很多插件/库在Vue3+Vite里用不了!比如Vuex3、Vue Router3、Element UI这些,都是专门给Vue2设计的,Vue3里要用Vuex4、Vue Router4、Element Plus这些Vue3版本的库;还有一些第三方库可能还没有更新Vue3版本,这时候怎么办呢?可以用vue-demi这个库,它是一个Vue2和Vue3的兼容层,能让部分Vue2的库在Vue3里运行,但不是所有库都支持,而且可能会有性能损耗,尽量还是用官方更新的Vue3版本,还有个小坑,有些插件/库的安装方式变了,比如Element Plus,在Vue2+Webpack里是直接在main.ts里引入整个库或者按需引入,在Vue3+Vite里按需引入更推荐用官方提供的unplugin-vue-components和unplugin-auto-import这两个插件,自动注册组件和自动导入API,不用手动import,非常方便。
第四个高频踩坑:热更新不生效!Webpack里热更新不生效可能是cache-loader的问题或者是模块路径的问题,Vite里热更新不生效的原因通常有这几个:一是修改的文件不在src目录下(public目录下的文件修改不会触发热更新,必须手动刷新页面);二是文件名的大小写不对,比如实际文件名是User.vue,但import的时候写的是user.vue,Linux系统下会区分大小写,热更新就不会生效;三是模块没有正确导出或者导入,比如export default写成了export,或者import的时候路径写错了;四是vite.config.ts里的hmr配置被关掉了,默认是开启的,不用改,还有个小技巧,如果热更新一直不生效,可以试试删除node_modules/.vite目录(这个目录是Vite的预构建缓存目录),然后重新启动开发服务器。
Vue3+Vite的90%常用场景,这些技巧足够应付!
第一个常用场景:页面权限控制,后台管理系统通常需要做页面权限控制,比如有些页面只有管理员才能访问,有些页面只有登录用户才能访问,在Vue3+Vite里,我们可以用Vue Router4的导航守卫(beforeEach)来实现,配合Pinia(状态管理库,Vue3官方推荐,比Vuex更简洁)存储用户的登录状态和权限列表,具体步骤大概是:在Pinia里创建一个user模块,存储用户的token、用户信息、权限列表;在路由配置里给每个需要权限的路由添加meta字段,比如meta: { requiresAuth: true, roles: ['admin'] };然后在router.beforeEach里判断用户是否登录,如果没有登录就跳转到登录页;如果登录了就判断用户是否有访问该页面的权限,如果没有就跳转到403页;如果都符合条件就放行,还有个小优化,可以用路由懒加载(const Home = () => import('@/views/Home.vue')),只在用户访问该页面的时候才加载对应的模块,减少首屏加载时间。 第二个常用场景:表单验证,表单验证是前端开发中最常用的功能之一,Vue3+Vite里可以用Element Plus或者Ant Design Vue自带的表单验证组件,也可以用VeeValidate这个专门的表单验证库(支持Vue3,功能更强大),比如用Element Plus的话,步骤大概是:给el-form组件绑定model和rules属性;给每个el-form-item组件绑定prop属性,prop属性的值要和model里的字段名一致;然后在rules里配置每个字段的验证规则,比如必填、长度、格式等等;最后在提交表单的时候调用el-form组件的validate方法,如果验证通过就提交,否则提示用户。 第三个常用场景:数据请求封装,Axios是目前最流行的HTTP请求库,在Vue3+Vite里我们可以对Axios做一个封装,统一处理请求拦截、响应拦截、错误提示、loading状态等等,具体步骤大概是:创建一个axios.js或者axios.ts文件,用axios.create创建一个实例,配置baseURL、timeout、headers等等;然后配置请求拦截器,在请求发送之前自动添加token到请求头里;配置响应拦截器,在响应返回之后统一处理成功响应和失败响应,比如失败响应的时候根据状态码提示用户(401跳转到登录页,403提示权限不足,500提示服务器错误);然后封装几个常用的请求方法,比如get、post、put、delete;最后在main.ts里把封装好的请求方法挂载到Vue.prototype上(Vue3里可以用app.config.globalProperties挂载,不过更推荐用provide/inject或者直接import的方式,避免全局污染)。 第四个常用场景:打包优化,刚才在新手入门里提到了几个基础的构建优化预配置,这里再补充几个进阶的:比如用rollup-plugin-visualizer这个插件,打包后生成一个可视化的打包体积分析报告,看看哪些模块占用的体积最大,然后针对性地优化;比如用unplugin-vue-components和unplugin-auto-import这两个插件不仅可以自动注册组件和自动导入API,还可以减少打包体积;比如用图片压缩工具(比如tiny-png或者vite-plugin-imagemin这个插件)压缩图片,减少图片体积;比如用代码分割工具(刚才提到的manualChunks)进一步拆分打包文件;比如用CDN加速常用的第三方库,比如把Vue、Vue Router、Pinia、Axios这些库换成CDN链接,打包的时候不把这些库打包进去,减少打包体积的同时利用CDN的缓存加速。
Vue3+Vite到底值不值得转?
如果你正在做一个新的Vue项目,那毫无疑问,直接选Vue3+Vite!不管是开发体验、还是生态支持,都是目前最好的选择;如果你正在维护一个Vue2+Webpack的旧项目,那就要看情况了:如果旧项目比较小,功能比较简单,而且没有特别紧急的需求,那可以先不转,继续用Vue2+Webpack;如果旧项目比较大,冷启动和热更新的速度已经严重影响了开发效率,而且有计划重构或者升级到Vue3,那可以考虑转Vue3+Vite,不过转的时候要做好充分的准备,比如先了解两者的核心差异,先补好关键配置,先测试常用的插件/库是否支持Vue3,不然会踩很多坑。 Vue3+Vite是前端开发的一个趋势,早学早受益,但也不用盲目赶时髦,要根据自己的实际情况来选择。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网

