vue-cli迁移vite,速度直接起飞

769 阅读5分钟

前言

在使用webpack构建项目,或直接用脚手架vue-cli构建的vue项目中,构建速度一直是个令人闹心的问题,有时项目庞大,依赖过多时,那速度更是令人堪忧,开发体验非常的差。于是我就想,vite都出来这么久了,可不可以把我现在在做的项目的构建工具换成vite呢?说干就干,谁怕谁!能跑就行。

了解vite

既然要使用vite构建,那么在使用之前,先简单了解下vite vite官网

迁移vite

大概了解了vite之后,接下来就是进行迁移工作了。

迁移前项目技术栈介绍

  • 技术栈: vue2.7(支持部分vue3的语法) + TypeScript(4.1.5) + vue-router(3.6.4) + vuex(3.4.0) + 其它
  • 构建工具:vue-cli (4.5.15)

注:由于使用的是vue2.7,项目中还使用了vue3的语法,所以在迁移过程中一些依赖的版本需要注意下,一不小心版本不兼容项目可能就跑不了了

删除不需要的依赖

  • 删除vue-cli相关的依赖

vue.config.js配置文件也可以删了

  • vite对常用的css预处理器提供了开箱即用的支持,所以sass-loader也可以删除

  • 删除vue模板编译器插件vue-template-compiler,vite这个将由vite的插件处理

  • babel相关的插件也删掉,不需要了 (Vite 以 原生 ESM 方式提供源码)

babel 相关的配置也删除掉

babel.config.js配置文件也可以删掉了

  • 其它不可用插件也需要删除,换成vite支持的,如果没有就可能需要自己写个vite插件或者使用别的替代方案

新增相关依赖

  • vite
  • node类型支持: @types/node
  • vue2解析: @vitejs/plugin-vue2
  • eslint: eslint(版本调整)、eslint-plugin-vue(版本调整)、@vue/eslint-config-typescript、vite-plugin-eslint
  • 浏览器兼容:@vitejs/plugin-legacy、terser

新增后如下,部分依赖需要注意下版本

添加vite配置文件vite.config.ts

直接上配置(需要更多自定义或扩展功能可以自行配置)

移动并修改index.html文件

  • 移动文件

在使用vue-cli构建时,index.html文件可能放在public文件夹中,改成vite构建后,入口文件是index.html,所以需要把index.html文件放到项目的根目录下

  • 修改index.html文件

去除文件中的占位符

// index.html

<!--remove-->
<title><%= htmlWebpackPlugin.options.title %></title> 
<!--add-->
<title>Hard Coded Title</title>

//...
<!--remove-->
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
<!--add-->
<strong>We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
// index.html

<!--remove-->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!--add-->
<link rel="icon" href="/favicon.ico">

javaScript已经不是自动注入了,需要手动引入

package.json修改运行脚本命令

配置环境变量

如果项目中需要用到环境变量,可以配置下环境变量

修改.eslintrc.js

供参考

集成TS类型检查工具vue-tsc

vite只有ts转译的功能,没有集成ts的类型检查,所以想要进行类型检查只能靠IDE或者自己配置集成

本项目将集成vue-tsc作为类型检查工具

首先安装vue-tsc依赖,这里建议版本不要高于1.0.8,不然可能追踪方法会报错导致检查报错

添加校验命令,这里打包的时候也添加了校验,校验失败就会打包失败(

配置到git提交代码之前校验,防止不规范代码的提交(结合husky工具使用)

对vue的template的校验比较恶心,可能还不成熟,个人觉得也没太必要校验,这个在tsconfig.json中配置下跳过就行

解决报错问题

迁移vite的配置相关工作已经基本完成了,接下来就是安装依赖,将项目跑起来了,如果你的项目小,代码少,运气好的话可能一次性就能跑成功了,但是正常项目这时候跑起来一般会有一大推报错,接下来就记录下本人迁移过程中遇到的一些错误及解决方案

  • eslint 代码检查方面的报错

解决这个问题就是按照eslint的配置规范修改代码,如果不想修改也可以修改eslint的配置(不建议这么做)

建议可以把eslint的问题放到最后解决,可以在vite.config.ts中先把eslint关了,等项目能够成功跑起来在打开解决eslint问题

  • 使用commonJs语法或者node专有的导致的报错问题

1、 process.env.BASE_URL process undefined

可以做以下修改

2、使用require导致的报错

可以改成import的方式显示的引入

使用new URL(url, import.meta.url)

import.meta.globEager替代require.context动态引入方案

  • 引入资源找不到问题

比如下面这个问题,引入的是一个静态资源目录中的一个文件

在vite的官网中发现了以下说明

所以需要避免下这种情况,可以考虑改成javaScript动态的方式,比如当前这个问题可以用以这个方法解决

  • 解决jsx报错问题

如果项目中使用了jsx语法,script需要加上lang="jsx"

  • sockjs-client包引入后包代码有报错

做以下修改解决

  • svg图标没了

本迁移项目中使用svg雪碧图,vue-cli构建时使用了svg-sprite-loader这个插件来进行加载,但是这个插件只支持webpack,所以在vite构建环境下是不可用的,这时候就需要寻找其它方法了

在网上找了一圈,没有找到比较好的现成可用的vite插件,于是就自己参考资料写了一个vite插件来处理svg,最后发布到公司内部的npm

插件代码比较少,逻辑也很简单,这里直接粘上代码供参考

const fs = require('fs')
let idPerfix = ''
const svgTitle = /<svg([^>+].*?)>/
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
const hasViewBox = /(viewBox="[^>+].*?")/g
const clearReturn = /(\r)|(\n)/g
// 查找svg文件
function svgFind (e) {
    const arr = []
    const dirents = fs.readdirSync(e, { withFileTypes: true })
    for (const dirent of dirents) {
        if (dirent.isDirectory()) arr.push(...svgFind(e + dirent.name + '/'))
        else {
            const svg = fs.readFileSync(e + dirent.name)
                .toString()
                .replace(clearReturn, '')
                .replace(svgTitle, ($1, $2) => {
                    let width = 0
                    let height = 0
                    let content = $2.replace(clearHeightWidth, (s1, s2, s3) => {
                        if (s2 === 'width') width = s3
                        else if (s2 === 'height') height = s3
                        return ''
                    })
                    if (!hasViewBox.test($2)) {
                        content += `viewBox="0 0 ${width} ${height}"`
                    }
                    return `<symbol id="${idPerfix ? idPerfix + '-' : ''}${dirent.name.replace(
                        '.svg',
                        ''
                    )}" ${content}>`
                })
                .replace('</svg>', '</symbol>')
            arr.push(svg)
        }
    }
    return arr
}
// 生成svg
exports.loadSvgSprite = (path, perfix = '') => {
    if (path === '') return
    idPerfix = perfix
    const res = svgFind(path)
    return {
        name: 'svg-transform',
        transformIndexHtml (dom) {
            return dom.replace(
                '<body>',
                `<body><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">${res.join('')}</svg>`
            )
        }
    }
}
  • 页面切换慢,特别是资源加载多的时候

针对这个问题,专门写了一篇文章总结了解决方案:vite构建的项目开发环境页面首次加载慢如何解决? - 掘金 (juejin.cn)

参考文档

cn.vitejs.dev/

rollupjs.org/

vueschool.io/articles/vu…