作为 Vue 生态的新一代构建工具,Vite 凭借「无需打包的开发服务器」「基于 esbuild 的极速编译」「按需编译的热更新」等特性,彻底解决了 Vue CLI(基于 Webpack)开发时的「启动慢、热更新卡、配置繁琐」等痛点。从 Vue CLI 迁移到 Vite 不是可选,而是提升开发效率的必然 —— 据实测,中等规模项目的开发启动时间可从 30 秒缩短到 2 秒,热更新响应从 500ms 压缩到 50ms 以内

本文将通过 5 个关键步骤,手把手教你完成从 Vue CLI 到 Vite 的迁移,附构建速度对比数据、配置转换工具推荐及避坑指南,确保迁移过程平滑无风险。

一、先看差距:Vue CLI 与 Vite 核心差异对比

在动手迁移前,先明确两者的核心区别,理解「为什么要迁移」:

维度Vue CLI(Webpack)Vite
开发服务器原理先打包所有模块(即使没用到),再启动服务器按需编译:只编译当前请求的模块,启动即就绪
编译工具基于 Babel(JavaScript)、css-loader(CSS)基于 esbuild(Go 编写,比 Babel 快 10-100 倍)
热更新(HMR)重新打包变更模块及依赖链,更新成本高直接更新变更模块,无需重新打包依赖
生产构建基于 Webpack,优化成熟但速度较慢基于 Rollup,配置更简洁,构建速度更快
配置复杂度需熟悉 Webpack 配置,常用功能需装插件(如 alias)内置大多数功能(alias、proxy 等),配置更直观
启动时间(中等项目)20-60 秒1-3 秒
热更新时间(组件修改)300-1000ms10-50ms

二、迁移前的准备:明确兼容性与目标

1. 检查项目兼容性

  • Vue 版本
    • Vue 3 项目:完全兼容 Vite,迁移成本最低;
    • Vue 2 项目:需额外安装 vite-plugin-vue2 插件(社区维护,兼容良好);
  • 依赖兼容性:确保项目依赖支持 ESM(ES 模块)—— 绝大多数现代库已支持,极少数老旧库(如仅提供 CommonJS 版本)需特殊处理(后文会讲)。

2. 目标与范围

  • 小项目:可一次性迁移,直接用 Vite 替代 Vue CLI;
  • 中大型项目:建议先并行运行(同时保留 Vue CLI 和 Vite 配置),逐步替换开发环境,最后切换生产构建。

三、5 个关键迁移步骤(附代码示例)

步骤 1:初始化 Vite 项目,迁移源码与依赖

核心任务:创建 Vite 项目骨架,迁移 src 源码、public 静态资源及依赖包。

操作步骤:
  1. 创建 Vite 项目(与原项目同级或重命名原项目):

bash

# 按提示选择框架(Vue)和语言(JavaScript/TypeScript)
npm create vite@latest my-vite-app 
cd my-vite-app
npm install
  1. 迁移源码与静态资源

    • 将原项目 src/ 目录(组件、JS/TS、CSS 等)复制到 Vite 项目的 src/
    • 将原项目 public/ 目录复制到 Vite 项目的 public/(Vite 对 public 资源的处理逻辑与 Vue CLI 一致:不经过编译,直接复制到输出目录)。
  2. 迁移依赖

    • 将原项目 package.json 中的 dependencies 和 devDependencies 复制到 Vite 项目(剔除 vue-cli-service@vue/cli-plugin-* 等 Vue CLI 相关依赖);
    • 安装 Vite 核心依赖:

    bash

    # Vue 3 项目
    npm install vue@3.x vue-router@4.x pinia@2.x # 确保 Vue 生态库版本兼容 Vite
    npm install vite @vitejs/plugin-vue -D
    
    # Vue 2 项目(需额外安装兼容插件)
    npm install vue@2.x vue-router@3.x vuex@3.x
    npm install vite @vitejs/plugin-vue2 -D # 社区提供的 Vue2 插件
    

步骤 2:配置文件迁移(vue.config.js → vite.config.js)

Vue CLI 用 vue.config.js 配置,Vite 用 vite.config.js,两者配置逻辑相似但语法不同,需重点迁移以下配置:

1. 基础配置(入口、输出、插件)

javascript

运行

// Vue CLI 旧配置(vue.config.js)
module.exports = {
  // 入口文件(默认 src/main.js)
  pages: {
    index: {
      entry: 'src/main.js'
    }
  }

// Vite 新配置(vite.config.js)
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue' // Vue3 插件(Vue2 用 @vitejs/plugin-vue2)

export default defineConfig({
  plugins: [vue()], // 注册 Vue 插件(必选)
  // 入口文件默认是 index.html(Vite 以 HTML 为入口,而非 JS)
  // 若需自定义入口,可在 index.html 中修改 <script src="./src/main.js"></script>
})

关键差异:Vite 以 index.html 为入口(而非 JS),需确保 index.html 中正确引入 src/main.js

2. 路径别名(alias)

javascript

运行

// Vue CLI 旧配置
const path = require('path')
module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        '@': path.resolve(__dirname, 'src'),
        'components': path.resolve(__dirname, 'src/components')
      }
    }
  }
}

// Vite 新配置
import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'), // 与 Vue CLI 一致
      'components': path.resolve(__dirname, 'src/components')
    }
  }
})
3. 开发服务器(代理、端口)

javascript

运行

// Vue CLI 旧配置
module.exports = {
  devServer: {
    port: 8080, // 端口
    open: true, // 自动打开浏览器
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        pathRewrite: { '^/api': '' }
      }
    }
  }
}

// Vite 新配置
export default defineConfig({
  server: { // 对应 devServer
    port: 8080,
    open: true,
    proxy: {
      '/api': {
        target: 'https://api.example.com',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '') // 注意:Vite 用 rewrite 而非 pathRewrite
      }
    }
  }
})
4. CSS 配置(预处理器、modules)

javascript

运行

// Vue CLI 旧配置
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        additionalData: `@import "@/styles/variables.scss";` // 全局注入变量
      }
    },
    requireModuleExtension: true // CSS Modules 文件名需带 .module
  }
}

// Vite 新配置
export default defineConfig({
  css: {
    preprocessorOptions: { // 对应 loaderOptions
      sass: {
        additionalData: `@import "@/styles/variables.scss";`
      }
    },
    modules: { // CSS Modules 配置
      // Vite 中 CSS Modules 需文件名带 .module(与 Vue CLI 一致)
      generateScopedName: '[name]__[local]___[hash:base64:5]'
    }
  }
})
5. 环境变量处理

Vue CLI 用 VUE_APP_ 前缀的环境变量(如 VUE_APP_API_URL),Vite 改用 VITE_ 前缀,需修改 .env 文件:

bash

# Vue CLI 旧文件(.env.development)
VUE_APP_API_URL = 'https://dev.api.com'

# Vite 新文件(.env.development)
VITE_API_URL = 'https://dev.api.com' # 前缀改为 VITE_

在代码中访问方式也需调整:

javascript

运行

// Vue CLI 旧写法
const apiUrl = process.env.VUE_APP_API_URL

// Vite 新写法
const apiUrl = import.meta.env.VITE_API_URL

步骤 3:处理依赖兼容性问题(CommonJS 模块、旧浏览器)

Vite 开发环境默认使用 ESM(ES 模块),若项目依赖中存在 CommonJS 模块(如老旧库),或需要支持 IE 等旧浏览器,需额外配置。

1. 处理 CommonJS 模块

部分老旧依赖(如 lodash@3.x)仅提供 CommonJS 版本,Vite 开发时会报错 require is not defined。解决方案:用 @vitejs/plugin-commonjs 插件转换:

bash

npm install @vitejs/plugin-commonjs -D

javascript

运行

// vite.config.js 中注册插件
import { defineConfig } from 'vite'
import commonjs from '@vitejs/plugin-commonjs'

export default defineConfig({
  plugins: [vue(), commonjs()] // 增加 commonjs 插件
})
2. 支持旧浏览器(如 IE11)

Vite 生产构建默认生成现代浏览器兼容的代码(ES6+),若需支持 IE11 等旧浏览器,需用 @vitejs/plugin-legacy

bash

npm install @vitejs/plugin-legacy -D

javascript

运行

// vite.config.js
import legacy from '@vitejs/plugin-legacy'

export default defineConfig({
  plugins: [
    vue(),
    legacy({
      targets: ['ie >= 11'], // 目标浏览器
      additionalLegacyPolyfills: ['regenerator-runtime/runtime'] // 额外的 polyfill
    })
  ]
})

步骤 4:构建优化与速度对比测试

迁移后需验证开发体验和生产构建是否符合预期,重点对比以下指标:

1. 开发环境速度对比
操作Vue CLI(中等项目)Vite(同等项目)提升倍数
冷启动(npm run serve)25 秒2 秒12 倍
首次加载首页800ms100ms8 倍
组件热更新(修改 .vue)600ms40ms15 倍
2. 生产构建优化(vite build)

Vite 生产构建基于 Rollup,默认优化已足够优秀,可额外配置:

javascript

运行

// vite.config.js 生产构建优化
export default defineConfig({
  build: {
    target: 'es2015', // 目标浏览器(影响代码转换)
    outDir: 'dist', // 输出目录(与 Vue CLI 一致)
    assetsDir: 'assets', // 静态资源目录
    sourcemap: process.env.NODE_ENV === 'production' ? false : 'inline', // 生产环境关闭 sourcemap
    rollupOptions: { // 自定义 Rollup 配置(如代码分割)
      output: {
        manualChunks: { // 拆分大型依赖为单独 chunk
          vendor: ['vue', 'vue-router', 'pinia'],
          utils: ['lodash', 'axios']
        }
      }
    }
  }
})

生产构建速度对比(中等项目):

  • Vue CLI(npm run build):45 秒
  • Vite(npm run build):18 秒(提升 2.5 倍)

步骤 5:渐进式迁移策略(大型项目适用)

大型项目无法一次性替换,可按以下步骤平滑过渡:

  1. 并行运行阶段

    • 保留 Vue CLI 配置(package.json 中保留 serve 脚本);
    • 新增 Vite 配置(添加 dev 脚本:"dev": "vite");
    • 开发时团队可自主选择 npm run serve(旧)或 npm run dev(新),确保业务不受影响。
  2. 功能验证阶段

    • 优先在新功能开发中使用 Vite,验证兼容性;
    • 逐步修复 Vite 环境下的报错(如依赖兼容性、配置问题)。
  3. 全面切换阶段

    • 确认所有功能在 Vite 环境下正常运行后,删除 Vue CLI 相关依赖和配置;
    • 生产环境构建切换为 vite build,并对比构建产物大小和运行效果(通常与 Vue CLI 构建产物差异极小)。

四、推荐工具:自动化配置转换与问题排查

  1. vue-cli-to-vite(配置自动转换):社区工具,可自动将 vue.config.js 转换为 vite.config.js,减少手动操作:

    bash

    npx vue-cli-to-vite
    
  2. vite-plugin-checker(类型与语法检查):在 Vite 开发时实时检查 TypeScript 类型和 ESLint 错误,替代 Vue CLI 的 eslint-loader

    bash

    npm install vite-plugin-checker -D
    
  3. Vite 官方调试工具:开发时访问 http://localhost:8080/__vite__,可查看模块依赖、热更新状态,辅助排查问题。

五、避坑指南:90% 开发者会遇到的 3 个问题

  1. public 目录资源引用路径错误

    • 错误:在代码中用相对路径引用 public 资源(如 ./public/logo.png);
    • 正确:public 资源需用根路径引用(如 /logo.png),Vite 会自动映射到 public 目录。
  2. CSS @import 路径解析问题

    • 错误:在 CSS 中用 @import '@/styles/vars.css'(Vite 对 CSS 中的 @ 别名支持需额外配置);
    • 正确:确保 vite.config.js 中 resolve.alias 配置正确,或用相对路径 @import '../styles/vars.css'
  3. 环境变量未生效

    • 错误:变量名未加 VITE_ 前缀,或在 vite.config.js 中用 process.env 访问(Vite 配置中需用 loadEnv 加载);
    • 正确:

      javascript

      运行

      // 在 vite.config.js 中加载环境变量
      import { loadEnv } from 'vite'
      export default defineConfig(({ mode }) => {
        const env = loadEnv(mode, process.cwd())
        console.log(env.VITE_API_URL) // 正确访问
        return { /* 配置 */ }
      })
      

六、总结:迁移后你将获得什么?

从 Vue CLI 迁移到 Vite,不是简单的工具替换,而是开发体验的「质变」:

  • 开发效率:冷启动从分钟级降到秒级,热更新从「等待反馈」变成「即时响应」,开发者无需再为工具等待;
  • 配置简化:告别复杂的 Webpack 配置,用更直观的 Vite 配置实现相同功能;
  • 生态兼容:完全支持 Vue 3 及现代前端工具链,为后续接入 TypeScript、SSR 等功能铺平道路。

按照本文的 5 个步骤,即使是大型项目也能平稳完成迁移。迁移后,你会发现开发过程中的「等待焦虑」大幅减少,更多精力可专注于业务逻辑实现。

至此,「Vue2 转 Vue3 全系列」文章已全部完结。从响应式原理到工程化迁移,我们覆盖了迁移过程中的核心知识点和实战技巧,希望能帮你顺利完成技术栈升级。最后赠送大家一篇vue3面试题总结。关注专栏,获取更多前端进阶干货~

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐