一、Vite 是什么?—— 面向未来的前端构建工具
Vite(法语意为“快”)是由 Vue 作者尤雨溪创建的新型前端构建工具。它利用浏览器原生支持 ES 模块(ESM)的能力,在开发环境下实现了极快的冷启动和热更新;而在生产环境中,则通过预构建依赖和 Rollup 打包输出高性能代码。
vite.config.js 作为 Vite 工程的核心配置文件,定义了整个项目的运行规则、编译逻辑和部署方案,是连接 Vite 核心能力与项目实际需求的桥梁,一份完善的 vite.config.js 能够让前端工程化流程更高效、更规范。
二、核心概念对比:Vite vs Webpack
虽然 Vite 和 Webpack 都用于构建前端应用,但它们的设计哲学完全不同,核心概念的差异直接决定了两者的使用体验和性能表现:
| 概念 | Webpack | Vite |
|---|---|---|
| Entry(入口) | 显式配置 entry 字段,从 JS 入口开始递归解析依赖 | 默认以 index.html 为入口,开发时按需加载 ESM 模块,生产环境可显式配置 HTML 入口 |
| Chunk(代码块) | 构建阶段静态分析生成 chunks | 开发时无需生成 chunk,生产构建依托 Rollup 实现动态代码拆分 |
| Loader(转换器) | 使用 loader 处理非 JS 资源(如 babel-loader, sass-loader) | 无明确 Loader 概念,通过插件机制 + 内置转换器处理特殊资源,更灵活高效 |
| Plugin(插件) | 插件监听生命周期钩子扩展功能 | 插件系统强大,支持开发、构建双模式介入,兼容部分 Rollup 插件 |
| Output(输出) | 输出 bundle 到指定目录,需额外配置优化 | 生产环境输出优化后的静态资源,内置多种打包优化策略,配置更简洁 |
关键区别:开发与生产环境的差异化处理
Webpack:开发和生产环境均走完整的打包流程,所有模块需提前编译合并为 bundle 文件,项目体积越大,启动和更新速度越慢。
Vite:
- 开发环境:基于浏览器 ESM 直接运行,不进行全量打包,仅对浏览器请求的模块进行即时编译,响应速度极快。
- 生产环境:使用 Rollup 进行完整打包,产出经过代码压缩、树摇优化、资源分类的静态资源,兼顾性能与兼容性。
这正是 Vite 能够实现“秒级启动”的根本原因,既保证了开发体验,又满足了生产环境的部署要求。
三、vite.config.js 核心模块配置实战
vite.config.js 采用模块化导出方式,支持根据环境动态返回配置,下面将按照功能模块拆解配置逻辑,详细说明各部分的配置目的和实现方式。
模块一:环境初始化与多环境配置
这是配置文件的前置步骤,核心是获取当前环境变量,实现不同环境下的差异化配置,依赖 Vite 内置的 loadEnv 方法。
配置逻辑
- 接收 Vite 传入的
mode参数,该参数对应启动/构建命令中的环境(如 development、production)。 - 通过
loadEnv加载对应环境的配置文件(如 .env.development、.env.production)。 - 定义不同环境下的公共路径、输出目录等核心配置,实现环境隔离。
代码实现
import { defineConfig, loadEnv } from 'vite';
import path from 'path';
import rimraf from 'rimraf';
// 生成时间戳,用于生产环境版本隔离
function createFileDate () {
const today = new Date();
const y = today.getFullYear();
const m = today.getMonth() + 1 > 9 ? today.getMonth() + 1 : '0' + (today.getMonth() + 1);
const d = today.getDate() > 9 ? today.getDate() : '0' + today.getDate();
const h = today.getHours() > 9 ? today.getHours() : '0' + today.getHours();
const M = today.getMinutes() > 9 ? today.getMinutes() : '0' + today.getMinutes();
return y + '' + m + '' + d + '' + h + '' + M;
}
export default ({ mode }) => {
// 第一步:加载环境变量,指定环境配置文件所在目录
const env = loadEnv(mode, path.join(process.cwd(), './env'));
const fileDateDir = createFileDate();
// 第二步:定义多环境核心配置项
// 生产环境 CDN 公共路径
const prodPublicPath = `https://yyt.com/resources/ph7/${fileDateDir}/`;
// 测试环境本地公共路径
const testPublicPath = '/ph7/';
// 第三步:生产环境前置清理旧构建产物
if (mode === 'production') {
rimraf(path.join(process.cwd(), './dist'), (err) => {
if (err) console.error('清理 dist 目录失败:', err);
});
}
// 返回最终配置
return defineConfig({
// 配置公共基础路径,根据环境切换
base: mode === 'production' ? prodPublicPath : testPublicPath,
// 其他核心配置...
});
};
配置说明
loadEnv第一个参数为环境模式,第二个参数为环境配置文件目录,会自动加载该目录下.env.${mode}格式的文件。- 生产环境构建前通过
rimraf清理旧的dist目录,避免旧资源残留导致部署问题。 - 公共路径
base用于配置打包后资源的根路径,生产环境配置 CDN 地址,测试环境配置本地子路径,解决资源 404 问题。
模块二:生产构建配置(build)
该模块是 vite.config.js 的核心之一,用于定义生产环境打包的输出规则、优化策略,所有配置均放在 build 字段下,依托 Rollup 实现打包能力。
配置逻辑
- 配置差异化输出目录,实现生产环境版本隔离。
- 开启输出目录自动清空,避免手动清理遗漏。
- 配置 Rollup 打包参数,包括入口、代码块输出规则、静态资源分类输出规则。
- 配置插件实现打包后资源自动拷贝,满足本地部署需求。
- 配置 SourceMap 生成规则,兼顾调试与安全。
代码实现
return defineConfig({
// 其他配置...
build: {
// 1. 差异化输出目录:生产环境带时间戳,测试环境简易目录
outDir: mode === 'production' ? `dist/cdn/${fileDateDir}` : 'dist',
// 2. 打包前自动清空 outDir 对应的目录
emptyOutDir: true,
// 3. 是否生成 SourceMap:开发环境生成,生产环境关闭(安全+减小体积)
sourcemap: mode === 'development',
// 4. Rollup 打包详细配置
rollupOptions: {
// 配置打包入口:指定 index.html 作为入口文件
input: {
main: path.resolve(__dirname, 'index.html')
},
// 配置输出规则
output: {
// 入口代码块输出规则:输出到 assets/js 目录,添加 hash 后缀
entryFileNames: 'assets/js/[name]-[hash].js',
// 公共/异步代码块输出规则:与入口代码块统一目录
chunkFileNames: 'assets/js/[name]-[hash].js',
// 静态资源分类输出规则:按文件类型拆分目录
assetFileNames: ({ name }) => {
if (name.endsWith('.css')) {
return 'assets/css/[name]-[hash][extname]';
}
if (name.endsWith('.html')) {
return 'assets/html/[name]-[hash][extname]';
}
if (
name.endsWith('.png') ||
name.endsWith('.jpg') ||
name.endsWith('.jpeg') ||
name.endsWith('.svg')
) {
return 'assets/img/[name]-[hash][extname]';
}
if (
name.endsWith('.xls') ||
name.endsWith('.xlsx') ||
name.endsWith('.csv') ||
name.endsWith('.pdf')
) {
return 'assets/files/[name]-[hash][extname]';
}
if (
name.endsWith('.ttf') ||
name.endsWith('.eot') ||
name.endsWith('.woff') ||
name.endsWith('.otf')
) {
return 'assets/fonts/[name]-[hash][extname]';
}
// 默认输出目录
return 'assets/[name]-[hash][extname]';
}
},
// 5. Rollup 插件配置:打包后资源拷贝
plugins: [
copy({
targets: [
{
src: [
`dist/cdn/${fileDateDir}/json`,
`dist/cdn/${fileDateDir}/locales`,
`dist/cdn/${fileDateDir}/index.html`
],
dest: 'dist/local'
}
],
// 打包完成后执行拷贝
hook: 'writeBundle',
// 扁平化目录结构,避免多级嵌套
flatten: true
})
]
}
},
});
配置说明
outDir定义打包输出目录,生产环境使用带时间戳的目录名,实现版本隔离,防止旧资源缓存导致线上问题。- Vite 生产打包(
vite build)时,默认会给静态资源文件(CSS/图片/字体等)添加内容哈希,规则是:文件名格式:[name].[hash].[ext](比如app.8a3b2.js)。对于普通 JS 文件,需通过配置entryFileNames/chunkFileNames手动添加 hash。 assetFileNames实现静态资源分类,将 CSS、图片、办公文件、字体分别放入对应目录,便于部署和运维排查。rollupOptions.plugins中配置rollup-plugin-copy,在打包完成后将核心资源拷贝到dist/local,满足本地测试部署需求。
模块三:静态资源扩展配置(assetsInclude)
Vite 有默认支持的静态资源类型,对于一些特殊格式的文件(如 xlsx、pdf),需要通过 assetsInclude 扩展识别,确保打包时能正确处理这些资源。
配置逻辑
- 以数组形式列出需要扩展的静态资源后缀。
- 配置在顶层字段中,全局生效。
代码实现
return defineConfig({
// 其他配置...
// 扩展静态资源类型识别
assetsInclude: [
'**/*.xlsx',
'**/*.xls',
'**/*.csv',
'**/*.pdf',
'**/*.png',
'**/*.jpg',
'**/*.svg'
],
});
配置说明
- 通配符
**/表示匹配所有目录下的对应文件。 - 配置后,这些特殊格式文件可以通过
import引入,打包时会按照build.rollupOptions.output中的规则输出到对应目录。
模块四:插件配置(plugins)
插件是 Vite 扩展功能的核心载体,通过配置不同插件,可以实现 Vue 解析、JSX 支持、HTML 优化等功能,所有插件配置在 plugins 数组中,按需求引入并初始化。
配置逻辑
- 安装所需插件(如
@vitejs/plugin-vue)。 - 在配置文件中导入插件。
- 在
plugins数组中初始化插件,传入必要的配置参数。
代码实现
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import { createHtmlPlugin } from 'vite-plugin-html';
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons';
return defineConfig({
// 其他配置...
plugins: [
// 1. 解析 Vue 单文件组件(.vue),Vue 项目必备
vue({
template: {
transformAssetUrls: {
video: ['src', 'poster'],
source: ['src'],
img: ['src'],
image: ['xlink:href', 'href'],
use: ['xlink:href', 'href'],
a: ['downloadHref']
}
}
}),
// 2. 支持 Vue JSX/TSX 语法解析
vueJsx({}),
// 3. HTML 优化插件:压缩 HTML、动态注入数据
createHtmlPlugin({
minify: true,
entry: 'src/main.js',
inject: {
data: {}
}
}),
// 4. SVG 图标管理插件:生成 SVG Sprite,实现图标复用
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: 'g-icon-[name]'
})
],
});
配置说明
@vitejs/plugin-vue:Vue 项目核心插件,用于解析.vue单文件组件,transformAssetUrls配置用于修正模板中资源的路径解析。@vitejs/plugin-vue-jsx:支持 JSX/TSX 语法,满足个性化编码需求,无需额外配置即可使用。vite-plugin-html:生产环境自动压缩 HTML,支持动态注入数据到 HTML 中,提升页面加载性能。vite-plugin-svg-icons:将指定目录下的 SVG 图标生成 Sprite,在项目中可通过<svg><use xlink:href="#g-icon-xxx"></use></svg>复用,避免图标重复引入。
模块五:路径别名配置(resolve.alias)
在大型项目中,相对路径(如 ../../../src/components/Modal)会降低开发效率和代码可维护性,通过 resolve.alias 配置路径别名,可简化模块引入路径。
配置逻辑
- 借助
path.resolve解析绝对路径。 - 在
resolve.alias中定义别名与对应目录的映射关系。
代码实现
return defineConfig({
// 其他配置...
resolve: {
// 优先解析 browser 字段和 module 字段
mainFields: ['browser', 'module'],
// 路径别名配置
alias: {
'@': path.resolve('./src'), // 映射 src 目录
'@LC': path.resolve('../lib-components/src'), // 映射外部组件库目录
'#': path.resolve('./types'), // 映射类型定义目录
'td-print': path.resolve('./node_modules/td-print/index.js') // 映射特定模块
}
},
});
配置说明
- 配置后,可使用
@/components/Modal替代../../../src/components/Modal,简化路径书写。 - 别名不仅支持目录映射,还支持单个文件映射(如
td-print):td-print是自定义模块别名,对应项目中./node_modules/td-print/index.js(前端打印相关第三方库);- 不配置别名时需写完整路径
import print from './node_modules/td-print/index.js',配置后可直接import print from 'td-print',简化导入、提升可读性。
path.resolve用于生成绝对路径,避免不同操作系统下的路径分隔符问题。- 补充:路径别名需配合编辑器配置(如
tsconfig.json/jsconfig.json的compilerOptions.paths),实现代码提示和跳转。
模块六:CSS 预处理器配置(css)
Vite 内置支持 SCSS、Less 等 CSS 预处理器,只需安装对应的依赖,再通过 css.preprocessorOptions 配置预处理器参数,即可正常使用。
配置逻辑
- 安装 SCSS 依赖(
sass,注意不是node-sass)。 - 在
css.preprocessorOptions.scss中配置编译参数、抑制弃用警告等。
代码实现
return defineConfig({
// 其他配置...
css: {
preprocessorOptions: {
scss: {
// 使用现代编译器 API,提升兼容性和编译性能
api: 'modern-compiler',
// 抑制 import 相关的弃用警告,保持构建日志整洁
silenceDeprecations: ['import']
}
}
},
});
配置说明
- 使用 SCSS 前需安装依赖:
npm install sass --save-dev。 api: 'modern-compiler'指定使用现代编译器 API,替代旧的node-sass编译器,提升编译速度和兼容性。silenceDeprecations用于抑制不必要的弃用警告,避免构建日志被冗余信息覆盖。
模块七:本地开发服务器配置(server)
该模块用于配置本地开发服务器的相关参数,包括端口、跨域代理、主机访问权限等,核心是通过 proxy 配置解决本地开发的接口跨域问题。
配置逻辑
- 配置服务器端口和主机访问权限。
- 通过
proxy配置接口转发规则,将前端请求转发到后端服务。 - 配置
changeOrigin实现跨域模拟,配置rewrite修正请求路径。
代码实现
return defineConfig({
// 其他配置...
server: {
// 配置本地开发服务器端口
port: 8387,
// 允许外部设备访问(如手机、同一局域网的其他电脑)
host: true,
// 跨域代理配置
proxy: {
// 匹配以 /charm 开头的请求
'/charm': {
// 后端服务目标地址
target: 'http://10.1.11.11:58***/',
// 开启跨域模拟:修改请求头中的 Origin 为目标地址
changeOrigin: true,
// 路径重写:此处保持原路径不变,可根据需求修改
rewrite: (path) => path.replace(/^\/charm/, '/charm')
},
// 可配置多个代理规则
'/g-filestore': {
target: 'http://10.5.11.11:8***/',
changeOrigin: true
}
}
},
});
配置说明
port配置本地开发端口,避免与其他服务端口冲突。host: true允许外部设备访问,方便在手机上调试移动端页面。proxy中的target为后端服务地址,changeOrigin: true是解决跨域的核心,通过修改请求头的 Origin 模拟同源请求。rewrite用于修正请求路径,若前端请求路径与后端接口路径不一致,可通过该配置进行调整。
模块八:全局常量注入配置(define)
通过 define 可以在项目中注入全局常量,这些常量会在打包时被静态替换,无需手动引入即可在代码中直接使用,适用于埋点、版本号、CDN 路径拼接等场景。
配置逻辑
- 在
define中定义全局常量,注意字符串类型需要使用JSON.stringify包裹。 - 在项目代码中直接访问该常量。
代码实现
return defineConfig({
// 其他配置...
define: {
// 注入时间戳全局常量,用于版本标识
'import.meta.env.VITE_APP_LOCAL_HASH': JSON.stringify(fileDateDir)
},
});
配置说明
define中的键名建议遵循import.meta.env.XXX格式,与 Vite 内置环境变量格式保持一致。- 字符串类型必须使用
JSON.stringify包裹,否则打包时会被当作变量解析,导致报错。 - 在项目代码中可直接使用:
console.log(import.meta.env.VITE_APP_LOCAL_HASH),打包后会被静态替换为对应的时间戳字符串。
四、Vite 的构建流程
尽管 Vite 采用了与 Webpack 不同的底层机制,但它依然遵循清晰的构建流程,分为开发环境和生产环境两个阶段:
1. 开发环境构建流程
- 初始化参数:解析 vite.config.js,合并命令行参数,加载环境变量和插件。
- 启动开发服务器:创建 HTTP 服务,监听指定端口,开启 WebSocket 通信(用于热更新)。
- 确定入口:加载根目录下的 index.html,自动修正其中的资源路径和公共基础路径。
- 按需编译模块:浏览器请求某个模块时,Vite 实时对该模块进行编译(如 Vue SFC 解析、TS 转 JS),修正依赖路径后返回给浏览器。
- 热更新(HMR):监听项目文件变化,仅重新编译修改的单个模块,通过 WebSocket 向浏览器推送更新通知,浏览器直接替换对应模块,无需全页刷新。
- 接口代理:根据 server.proxy 配置,将前端请求转发到后端服务,解决跨域问题。
2. 生产环境构建流程
- 环境准备:解析 mode 参数,加载对应环境变量,清理旧的打包产物。
- 初始化编译器:合并 vite.config.js 中的 build 配置,初始化 Rollup 编译器,注册所有插件。
- 解析入口与依赖:以 index.html 为入口,递归分析所有模块的依赖关系,构建完整的依赖图谱。
- 模块编译与优化:对所有模块进行编译转换,执行 Tree Shaking 剔除死代码,进行代码压缩和混淆。
- 组装与输出资源:将模块组装为入口代码块、公共代码块,按照配置的输出规则将静态资源写入指定目录。
- 后续自动化操作:执行插件的 writeBundle 钩子(如资源拷贝),生成最终的打包产物,完成构建。
五、Vite 的核心优势与适用场景
核心优势
- 极速启动:利用浏览器原生 ESM,无需全量打包,开发环境启动速度远超传统打包工具。
- 快速热更新:仅更新修改的单个模块,热更新响应无延迟,大幅提升开发效率。
- 丰富的插件生态:支持 Vue、React、TypeScript 等主流技术栈,兼容部分 Rollup 插件,扩展能力强。
- 开箱即用:内置 TypeScript、JSX、CSS 预处理器等支持,无需额外复杂配置。
- 高度可配置:vite.config.js 提供完善的配置项,可满足各类项目的工程化需求。
- 优化的生产打包:基于 Rollup 实现,产出的静态资源体积小、性能优,满足生产环境部署要求。
适用场景
- 新一代 SPA/MPA 项目开发。
- 前端组件库开发。
- 内部中后台系统、管理平台开发。
- 需要快速迭代的原型项目。
- 注重开发者体验的团队和项目。
六、总结
vite.config.js 作为 Vite 项目的核心配置文件,涵盖了环境配置、打包输出、插件扩展、本地开发等多个模块,一份完善的配置能够让前端工程化流程更规范、更高效。
Vite 凭借“开发环境按需编译、生产环境 Rollup 打包”的差异化策略,既解决了传统打包工具的性能瓶颈,又满足了生产环境的部署要求,是现代前端开发的优质选择。掌握 vite.config.js 的配置逻辑,能够充分发挥 Vite 的核心优势,助力项目高效开发与部署。