likes
comments
collection
share

记一次webpack转vite踩坑之路

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

背景

公司的h5项目越来越大,打包进度展示2万+模块, 尽管从webpack2升级到webpack4,冷启动仍需三分多钟,热更新10s左右,占用电脑内存也大,开发体验较差;查阅了很多资料,决定在运行项目时使用vite,提高效率。

冷启动数据 记一次webpack转vite踩坑之路 热更新数据 记一次webpack转vite踩坑之路

工具

使用的辅助工具为webpack-to-vite originjs.org/guide/tools…

过程

1,安装并运行命令

$ npm install @originjs/webpack-to-vite -g
$ webpack-to-vite <project path>

运行完命令,会在与项目平行的目录copy出一份代码,并可以看到目录下更改了三个文件,conversion.log,index.html(引入vite的main.js),vite.config.js(vite运行配置文件),package.json(引入vite相关包与命令)。

记一次webpack转vite踩坑之路

2,package.json引入了新包,重新删除node_modules, install一下并运行

记一次webpack转vite踩坑之路 记一次webpack转vite踩坑之路

3,发现一些包报node版本警告和报错,这个报错查了一下也是node版本问题,经过多次查资料和调试,将node版本升到16.8.0

记一次webpack转vite踩坑之路

4,node-sass报错

记一次webpack转vite踩坑之路 node-sass报错,node-sass 已经弃用了 直接安装sass 即可正常使用

5,运行成功,但是报了很多没安装的文件报错

记一次webpack转vite踩坑之路

原因是在webpack里配置了很多alias,在vite里面拿不到,将webpack里面的alias和externals(vite-plugin-externals)在vite里面也配置一下,重新运行

记一次webpack转vite踩坑之路

6,配置后运行起来后报错global is not defined

index.js?v=7841fec2:23 Uncaught ReferenceError: global is not defined
    at <stdin> (index.js?v=7841fec2:23:35)
    at __require (index.js?v=7841fec2:3:50)
    at index.js?v=7841fec2:1479:16

记一次webpack转vite踩坑之路

这个查了好久,我window定义和在vite配置里定义也不行,在vite配置文件里配置也不行,最后发现是'@originjs/vite-plugin-commonjs'插件问题,将timsdk的包转出问题了,人家本来是好的。目前该插件还有部分语法不支持,而且感觉不成熟,我一些注释掉的代码也会转换报错,先把它注释掉并运行

7,运行后报错require is not defined(解决完这个基本能把代码跑起来了)

api.js:10 Uncaught ReferenceError: require is not defined
    at api.js:10:18

vite不支持require,能import引入的尽量用import吧,因为viteCommonjs造成了上一个报错还无法使用,又暂时还没有找到其他的扩展可以很好的处理这个问题。 注:不过require.context不用手动做处理,有ViteRequireContext帮我们解决。 解决: 将源代码中的require替换为import。

8,本地图片引入问题,需要兼容webpack与vite。参考:

github.com/jestjs/jest…

juejin.cn/s/import.me…

blog.csdn.net/weixin_4221…

代码(这里的代码在webpack打包时还有问题,下面会说到)

// 获取本地图
function getLocalAssetsImages(url) {
  if (process.env.VITE) {
    // return new URL(`/src/${url}`, import.meta.url).href
    return `${location.origin}/src/${url}`
  } else {
    return require(`@/${url}`)
  }
}

9,webpack打包报警告

webpack打包后发现一堆警告 记一次webpack转vite踩坑之路

搜索了很多博客,最终发现发现是eslint和node版本问题github.com/SublimeLint…

找到合适的eslint版本和相关依赖包并升级"eslint": "^3.19.0", =》 "eslint": "^7.5.0"

升级完eslint运行出现了很多报错,很多确实存在问题,批量修复了,但是有些规则自动修复不了,而且项目又大又老文件成千上万个,就暂时屏蔽掉了,遇到一个再改一个

10,webpack打包成功但是分包功能丢失了

基本改造完成后,vite和webpack都可以正常运行,但是webpack打包出来原来的分包功能没有了,而且连一些报了一些readme警告,之前都是没有的。

排查:

1,因为升级了node等,我第一时间反应是不是包组件的兼容问题,找了很多相关的babel包版本,比如babel-plugin-dynamic-import-node,babel-plugin-import,但是都不行,后面直接对比之前的版本,甚至直接用之前的node_models包都不行。
2,后面发现想想一些readme文件根本没引用都报了错,应该是某个地方的代码把它引入了,果然发现之前的一处地方,为了兼容webpack和vite取本地图片,写了一个方法,
// 获取本地图
function getLocalAssetsImages(url) {
  if (process.env.VITE) {
    // return new URL(`/src/${url}`, import.meta.url).href
    return `${location.origin}/src/${url}`
  } else {
    return require(`@/${url}`)
  }
}

记一次webpack转vite踩坑之路

这种时候(require(@/${url}))静态分析并不能确切的知道打包src(@)下的哪个文件。此时webpack会打包src下的所有文件。所以会看到'./src ^./.*$ '这样的路径,使用require.context引入到具体文件夹下解决,参考segmentfault.com/q/101000001…

// 获取本地图
function getLocalAssetsImages(url) {
  if (process.env.VITE) {
    // return new URL(`/src/${url}`, import.meta.url).href
    return `${location.origin}/src/${url}`
  } else {
    let imgNameSrc = ``
    if (url) {
      let params = url.split('/')
      let imgName = params[params.length - 1]
      imgNameSrc = `./${imgName}`
    }
    let requireContext = require.context('@/assets/img/function', false)
    return requireContext(`${imgNameSrc}`)
  }
}

11,打包后发布有一个404 main.js空包

记一次webpack转vite踩坑之路 由于vite需要引入main.js, webpack打包出来后,会加载这个空包,在html里判断一下,是webpack的时候不加载空包


import { createHtmlPlugin } from 'vite-plugin-html'
plugins: [
    createHtmlPlugin({
      inject: {
        data: {
          process: ''
        }
      }
    })
]
<!-- process 在webpack内有,在vite内没有,通过createHtmlPlugin注入process: '', 是vite的时候才加载/src/main.js-->
<% if (process) { %>
<% } else {%>
  <script type="module" src="/src/main.js"></script>
<% } %>

12,其他问题

其他插件版本问题报错

12,其他优化

懒加载

本来是使用html cdn引入,首屏非必须的包通过使用懒加载,如下包均优化

echarts,vconsole,vue-video-player,vue-video-custom-theme.css,video.min.js,video-js.css

13,最终成果

升级完成项目启动由约3min多减少约2s内, 代码更新效果时间约10s减少到无感, 代码包体积减少20MB, 首屏加载减少0.7s

打包体积旧

记一次webpack转vite踩坑之路

打包体积新(升级了node等,意外收获)

记一次webpack转vite踩坑之路

webpack冷启动

记一次webpack转vite踩坑之路

vite冷启动

记一次webpack转vite踩坑之路

webpack热更新

记一次webpack转vite踩坑之路

vite热更新无感

记一次webpack转vite踩坑之路

14,参考文章

Webpack to Vite | Origin.js

(node:52739) Warning: Accessing non-existent property 'cat' of module exports inside circular dependency · Issue #1783 · SublimeLinter/SublimeLinter · GitHub

GitHub - originjs/webpack-to-vite: Convert a webpack/vue-cli project to vite project. 将 webpack/vue-cli 项目转换为 vite 项目。

成功解决:Can‘t find Python executable “python“, you can set the PYTHON env variable. - 郑-某 - 博客园

Error: Can't find Python executable "python", you can set the PYTHON env variable.解决办法 - 简书

(21条消息) 【Node Sass version 8.0.0 is incompatible with ^4.0.0.问题解决】_悰小风子的博客-CSDN博客

vite 不支持requrie require is not defined - 简书

vite 配置eslint - 简书

(21条消息) vite配置eslint_ZGSouth的博客-CSDN博客

import.meta.url webpack4-掘金

less使用绝对路径@import导入文件 - 掘金

[Bug]: SyntaxError: Cannot use 'import.meta' outside a module · Issue #12183 · jestjs/jest · GitHub

(24条消息) vue3 vite版本 引入本地静态图片的方式_vue3引入本地图片_xiexikk的博客-CSDN博客

踩坑日记:如何修复“Issues with peer dependencies found ”错误 - 知乎

(24条消息) 详细记录前端项目使用import懒加载组件打包失败的踩坑之路_YorcentLuo的博客-CSDN博客

(24条消息) 【已解决】There are multiple modules with names that only differ in casingThis can lead to unexpected错误解决_海海不掉头发的博客-CSDN博客

javascript - webpack将打包目录下的md、html文件解析了 - SegmentFault 思否

(24条消息) js中动态获取页面的script地址,并动态给他添加script标签和地址,解决页面白屏问题_妍崽崽@的博客-CSDN博客

配置antd的externals之后,antd还是会被打包进去 🐛[BUG] · Issue #5720 · ant-design/ant-design-pro · GitHub

(25条消息) vue2x版本index.html种获取环境变量_vue index.html 如何获取环境变量_momo_mom177的博客-CSDN博客

(25条消息) vue3+vite 在html文件中添加环境变量_一缕阳光@的博客-CSDN博客

转载自:https://juejin.cn/post/7253816086679093308
评论
请登录