likes
comments
collection
share

Webpack to Vite踩坑指北

作者站长头像
站长
· 阅读数 13

大家好,我是苏先生,一名热爱钻研、乐于分享的前端工程师,跟大家分享一句我很喜欢的话:人活着,其实就是一种心态,你若觉得快乐,幸福便无处不在

github与好文

前言

最近闲来无事,总是摸鱼总归是不太好。刚好公司的项目使用的是webpack,正好借此机会做下迁移,并将该过程记录。当前项目使用webpack+vue2

对比

这里挑选了一个比较复杂的路由页面,分别使用vite和webpack启动,记录从npm run start到页面加载的耗时

  • vite

Webpack to Vite踩坑指北

  • webpack

Webpack to Vite踩坑指北

基础改造

  • package.json中新建指令

Webpack to Vite踩坑指北

  • alias别名

和webpack一样,配置resolve.alias

Webpack to Vite踩坑指北

  • 全局变量注入

使用vite内置的define代替webpack的DefinePlugin

Webpack to Vite踩坑指北

  • proxy代理

定义server.proxy代替webpack的proxyTable,写法上仅框红的一处不太一样

Webpack to Vite踩坑指北

  • 适配vue2

yarn add vite-plugin-vue2,并在vite.config.js中引入并注册使用

Webpack to Vite踩坑指北

错误修复

  • 白屏

1.报错

运行npm run dev:vite后打开浏览器,页面空白,可以看到入口的index.html中并没有引入script标签

Webpack to Vite踩坑指北

2.修复

yarn add vite-plugin-html,并在vite.config.js中引入并注册使用,其entry配置项即可帮助我们自动注入script标签

Webpack to Vite踩坑指北

  • 默认扩展名称

1.报错

不指定.vue扩展名称,会报如下错误

Webpack to Vite踩坑指北

点开该报错,感觉app并不是一个正常的文件

Webpack to Vite踩坑指北

故找到引用处,尝试添加.vue扩展名后重启,报错如下

Webpack to Vite踩坑指北

2.修复

此时已经基本可以确定是省略扩展名称导致的了,故在resolve中增加如下配置

Webpack to Vite踩坑指北

  • require语法报错

1.报错

Webpack to Vite踩坑指北

2.修复

在webpack中能直接使用是因为其内部帮我们做了处理,在vite中需要单独引入插件(yarn add vite-plugin-require-transform)

Webpack to Vite踩坑指北

  • 替换global

1.报错

Webpack to Vite踩坑指北

2.修复

查看报错语句

Webpack to Vite踩坑指北

可以看到,其使用三元运算做了“降级处理”,理论上来说使用false的结果也问题不大

故,使用window来代替global

Webpack to Vite踩坑指北

  • 修改vue引用版本

1.报错

Webpack to Vite踩坑指北

2.修复

这是由于vue包中默认导出的是runtime版本,修改下之前定义的别名即可

Webpack to Vite踩坑指北

  • 依赖注入

1.报错

Webpack to Vite踩坑指北

2.修复

在webpack中通过ProvidePlugin提前注入相关依赖而不需要在页面中显示引入,在vite中可以使用@rollup/plugin-inject来代替

Webpack to Vite踩坑指北

  • 插件报错

1.报错

Webpack to Vite踩坑指北

2.修复

由于本次目的仅仅是为开发环境做改造,故为了尽可能少的影响生产,这里随便写个插件过滤下

Webpack to Vite踩坑指北

  • vite-plugin

1.报错

Webpack to Vite踩坑指北

2.修复

这是之前我优化面包屑时候写的webpack的loader,需要按照vite插件的语法格式做下替换,将直接export的方式改为返回一个包含name和transform的对象的函数即可

Webpack to Vite踩坑指北

  • 内置模块

1.报错

Webpack to Vite踩坑指北

2.修复

项目中大量使用了node的timers模块的setTimeout方法,这在vite中被视为内置模块是不允许被客户端调用的,估计当初是不小心自动引入的,同样的,我们在插件中识别并替换掉

Webpack to Vite踩坑指北

  • mqtt

报错如下

Webpack to Vite踩坑指北

查看相关代码,感觉是process相关的错误

Webpack to Vite踩坑指北

故尝试安装process包,并通过inject进行注入

Webpack to Vite踩坑指北

  • 样式

1.报错

Webpack to Vite踩坑指北

2.修复

这是因为‘~’符号不被vite识别,因为该符号是vue-cli中的用法,去掉即可

Webpack to Vite踩坑指北

  • 失效

1.问题

Webpack to Vite踩坑指北

2.修复

在index.html中以cdn的方式引入,这虽然会对生产产生一定的影响,不过理论上其影响可以被忽略

Webpack to Vite踩坑指北

  • 默认间隙

1.问题

目前发现的,按钮之间的默认的空隙没了

Webpack to Vite踩坑指北

2.修复

修改默认编译方式为preserve就可以了

Webpack to Vite踩坑指北

  • 路由改造

由于vite本身就是按需加载的,则我们在路由中进行的懒加载就显得有点鸡肋,而且还会影响vite的预构建行为

Webpack to Vite踩坑指北

故考虑将路由引用方式做调整,同样出于仅作用于本地开发环境的考虑,需要在plugin阶段做下转换,即:

1.将如下引入方式

Webpack to Vite踩坑指北

通过plugin替换为如下形式

Webpack to Vite踩坑指北

则随便写点正则

Webpack to Vite踩坑指北

替换结果如下

Webpack to Vite踩坑指北

取舍

这确实能有效避免二次预构建行为,也确实有效的提高了部分页面首次加载的时间,但是却导致首屏加载被拖到和webpack持平了,因此到底要不要改造路由方式就仁者见仁了.....

题外话

其实webpack5的持久缓存已经可以做到和vite不分伯仲了,而且webpack5也提供了类似vite的构建方式,感兴趣的可以看我这篇文章:传送门


如果本文对您有用,希望能得到您的点赞和收藏

订阅专栏,每周更新1-2篇类型体操,每月1-3篇vue3源码解析,等你哟😎