从 Vue CLI 到 Vite,10分钟迁移指南

职场   科技   2024-11-18 10:11   浙江  

如果你是在2021年之前使用Vue进行开发,那么你选择的构建工具大概率是Vue CLI。

Vue CLI在很长一段时间一直是脚手架Vue.js项目的标准。

不过现在,Evan You的下一代构建工具,Vite,很有可能将成为Vue CLI的绝佳替代品。

为什么要从Vue CLI迁移到Vite?

主要原因在于速度。

Vite的开发服务器速度很快,因为它对JavaScript模块使用本机浏览器支持,所以服务器启动时间是即时的。

而且无论应用程序的大小如何,热模块更换始终保持高速,因为不必重建整个捆绑包。

下面我们来比较一下分别使用Vue CLI与Vite但两个完全相同的项目。

  • 启动时间:
    • Vue CLI - 2591 毫秒(超过2秒)
    • Vite - 259 毫秒(远低于半秒 – 比Vue CLI快了10倍)
  • 热模块更换 (HMR):
    • Vue CLI - 171ms
    • Vite - 不是由Vite打印到控制台,基本上是即时的

而这还只是脚手架样板。

随着项目的增长,Vue CLI版本只会逐渐变慢,而Vite可以确保无论项目规模如何,都能以相同的水平执行。

如何从Vue CLI迁移到Vite

既然Vite如此强大,那么如何将项目从Vue CLI迁移到Vite呢?

为了回答这个问题,我用Vue CLI构建了一个新项目,让我们一起逐步将这个项目迁移到Vite。

另外,示例用的是Vue 2代码库。Vue 3的情况会有所不同。

步骤#1:更新依赖项

迁移到Vite的第一步是更新package.json中的依赖项。我们需要删除与Vue CLI相关的依赖项。

// package.json
"@vue/cli-plugin-babel""~4.5.0", // remove
"@vue/cli-plugin-eslint""~4.5.0", // remove
"@vue/cli-plugin-router""~4.5.0", // remove
"@vue/cli-plugin-vuex""~4.5.0", // remove
"@vue/cli-service""~4.5.0", // remove

我们还可以删除sass-loader,因为Vite为最常见的预处理器提供了开箱即用的内置支持。

因此我们依然能继续使用我们选择的CSS预处理器。

请注意,Vite建议将原生CSS变量与PostCSS插件一起使用,这些插件可以实现CSSWG草稿并编写简单的、符合未来标准的CSS。

// package.json
"sass-loader""^8.0.2" // remove

最后,添加Vite作为依赖项,以及Vue插件组件以支持单文件组件。

// package.json
"@vitejs/plugin-vue""^1.6.1",
"vite""^2.5.4",

此外,由于我们正在迁移Vue 2项目,所以除了官方的Vue插件之外,还需要包含Vue 2社区维护的Vite插件。

当然,如果使用的是Vue 3,那就没有必要了。

// package.json
"vite-plugin-vue2" : "1.9.0" // add for Vue 2

安装了Vite插件后,我们现在删除vue模板编译器,因为现在它由Vite Vue插件处理。

// package.json
"vue-template-compiler""^2.6.11" //remove (SFC support provided by vite vue plugin)

步骤#2:仅为现代浏览器提供支持

Vite是下一代构建工具,仅支持最现代的浏览器。

事实上,我们可以从依赖项中完全删除Babel,因为大多数移动和桌面常青浏览器几乎完全支持所有ES6功能。

如果你仍然需要支持像Internet Explorer 11这样的旧浏览器,Vite也提供官方插件。

要删除Babel,首先要删除babel.config.js文件。

接着,由于我们已经删除了需要babel本身的@vue/cli-plugin-babel依赖项,因此只需要从package.json中删除其他几个babel相关的依赖项。

// package.json
"babel-eslint""^10.1.0", // remove
"core-js""^3.6.5", // remove

删除了babel-eslint之后,我们需要将其作为解析器从.eslintrc文件中删除。

// .eslintrc
// remove
parserOptions: {
    parser: "babel-eslint",
},

注意:如果你的项目中没有linting/format设置,那么可以跳到下一步。

最后,我们需要在.eslintrc中添加环境es2022,因为项目的src现在完全位于ES模块上。

你也可以保留node env,因为有些配置文件仍在节点环境中运行。

// .eslintrc
env: {
    node: true,
    es2022: true, // 👈 add this
}

此更改还将迫使我们更新eslint本身,以及eslint-plugin-vue以支持es2021环境。

$ npm install eslint@8 eslint-plugin-vue@8

步骤#3:添加Vite配置

Vite通过项目根目录中的vite.config.js文件进行配置。

默认的vite.config.js文件在使用npm init vite@latest为Vue生成一个全新的Vite项目时是这样做的:

// vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()]
})

还要再做两件事。

第一件事是从vite-plugin-vue2导入Vue插件。

// vite.config.js
import vue from '@vitejs/plugin-vue' // remove
import { createVuePlugin as vue } from "vite-plugin-vue2";

//...

当然,如果你使用的是Vue 3,那就没有必要了。

第二件事是为了让@import别名像在Vue CLI中那样工作。

// vite.config.js
//...
const path = require("path");
export default defineConfig({
  //...
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

步骤#4:移动index.html

与Vue CLI相反,Vite实际上将保存Vue.js应用程序的index.html文件放在项目的根目录中而不是公共目录中,因此需要移动文件。

并且在index.html中还需要进行一些更改。

首先,将<%= htmlWebpackPlugin.options.title %>占位符的实例更改为硬编码值。

// 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>

再将<%= BASE_URL %>占位符替换为绝对路径。

// index.html

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

最后也是最重要的一点,因为JavaScript应用程序不再是自动注入的,所以我们需要像这样做:

<script type="module" src="/src/main.js"></script>

步骤#5:更新脚本

回到package.json,我们还需要更新脚本。

需要将旧的vue-cli-service命令更改为Vite特定命令。

// package.json
"serve""vue-cli-service serve", // remove
"build""vue-cli-service build", // remove
"dev""vite",
"build""vite build",
"serve""vite preview",

注意,启动开发服务器的命令不再是serve

Vite改用dev,而serve用于在本地预览生产版本。

此外,如果你启用了linting,则应更新lint脚本以直接运行eslint

"lint""eslint --ext .js,.vue --ignore-path .gitignore --fix src"

步骤#6:更新环境变量

环境变量在Vite中的工作方式与它们在Vue CLI中的工作方式之间存在很多交叉。

例如,.env命名约定可以保持不变。

.env                # loaded in all cases
.env.local          # loaded in all cases, ignored by git
.env.[mode]         # only loaded in specified mode
.env.[mode].local   # only loaded in specified mode, ignored by git

但是,你无法再访问process变量上的环境变量,而是可以在import.meta.env上找到这些变量。

// router/index.js
base: process.env.BASE_URL, //remove
base: import.meta.env.BASE_URL,

此外,VUE_APP_前缀(用于使得声明客户端公开的env变量更明显)被更改为VITE_,因此如果你有此类环境变量,则必须相应地进行更新。

步骤#7:将.vue扩展名添加到SFC导入

我们必须确保单个文件组件的所有导入都以.vue扩展名结尾。

// Home.vue
import HelloWorld from "@/components/HelloWorld.vue"; // .vue is required

如果此过程由于代码库的尺寸而过于繁琐,你也可以选择配置vite。

实现方法是将.vue添加到vite.config.js中的resolve.extensions config选项。

你还需要确保手动包含所有默认扩展名,因为此选项会覆盖默认值。

// vite.config.js
//...
export default defineConfig({
  plugins: [vue()],
  resolve: {
    extensions: ['.mjs''.js''.ts''.jsx''.tsx''.json''.vue'],
    //...
  },
});

虽然这有用,但如果可能的话,还是应该避免这样做。为什么?

根据Vite文档:“请注意,不建议省略自定义导入类型(例如.vue)的扩展名,因为会干扰IDE和类型支持。”

步骤#8:清理魔术注释

最后,你可以删除所有用于命名动态导入的魔术注释,因为这些注释特定于webpack,对Vite没有任何意义。

// router/index.js
import(
    /* webpackChunkName: "about" */  // remove
    "../views/About.vue"
),

相反,Vite将根据原始.vue文件名和缓存破坏哈希自动命名块,就像这样:About.37a9fa9f.js

步骤#9:享受更快、更无缝的开发体验

完成上述步骤1-8后,你的应用程序就可以开始准备使用Vite运行了!使用npm run dev启动开发服务器,看看Vite有多快。

享受迁移之后更快、更无缝的开发体验吧。

前端新世界
关注前端技术,分享互联网热点
 最新文章