import { resolve } from 'node:path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import { loadEnv } from 'vite'
import vueJsx from '@vitejs/plugin-vue-jsx'
import pkg from './package.json'
import dayjs from 'dayjs'
// process.cwd() 是 Node.js 的内置方法,用于获取 Node.js 进程的当前工作目录,在 Vite 配置中,这个值通常指向项目根目录
// 使用 process.cwd() 而不是 __dirname 的原因如下:
// 1. 灵活性:process.cwd() 返回的是 Node.js 进程的当前工作目录,通常是执行命令时所在的目录
// 2. 一致性:无论 Vite 配置文件位于项目的哪个位置,CWD 始终指向项目根目录
// 3. 环境变量加载:CWD 可以确保从项目根目录正确加载环境变量文件 .env
const CWD = process.cwd()
// https://vite.dev/config/
// vite.config.js 文件需要基于(`serve` 或 `build`)命令或者不同的环境变量来决定选项,则需要 defineConfig((param) => object) 方式配置 vite.config.js
export default defineConfig(({command, mode}) => {
console.log('command =>', command); // 使用 pnpm dev 运行项目时: command => server; 使用 pnpm build 运行项目时: command => build
console.log('mode =>', mode); // 使用 pnpm dev 运行项目时: mode => development; 使用 pnpm build 运行项目时: mode => production
// 类型签名:function loadEnv(mode: string, envDir: string, prefixes: string | string[] = 'VITE_'): Record<string, string>
// 加载 envDir 中的 .env 文件。默认情况下只有前缀为 VITE_ 会被加载,除非手动设置第三个参数 prefixes
const { VITE_BASE_URL, VITE_DROP_CONSOLE } = loadEnv(mode, CWD)
return {
// 如果你需要在嵌套的公共路径下部署项目,只需指定 base 配置项,然后所有资源的路径都将据此配置重写
// 用于指定项目在部署时的公共基础路径。它会影响以下几个方面
// 构建时的资源路径:所有静态资源(JS、CSS、图片等)都会以该路径为前缀
// 开发服务器的路径:开发服务器会将该路径作为基础路径提供服务
// 路由基础路径:单页应用的路由会基于该路径进行配置
base: VITE_BASE_URL,
// 定义全局常量替换方式。其中每项在开发环境下会被定义在全局,而在构建时被静态替换;
// 注意: 对于使用 TypeScript 的开发者来说,请确保在 global.d.ts 文件中添加类型声明(参见:“文件类型声明” 一文),以获得类型检查以及代码提示。
define: {
__APP_INFO__: JSON.stringify({
pkg,
lastBuildTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
}),
},
// 若要使用一个插件,需要将它添加到项目的 devDependencies 并在 vite.config.js 配置文件中的 plugins 数组中引入它
// 需要用到的插件数组
plugins: [
vue(),
vueDevTools(),
// 提供 Vue 3 JSX 支持
// 参考文档:https://www.npmjs.com/package/@vitejs/plugin-vue-jsx
// 安装插件:pnpm add @vitejs/plugin-vue-jsx --save-dev
vueJsx({
// options are passed on to @vue/babel-plugin-jsx
}),
// 集成 UnoCss 插件,详情查看【配置 unocss.config.ts】文章
UnoCSS(),
],
// 用于配置模块解析相关的行为,它会影响 Vite 如何查找和解析模块。主要功能包括:
// 1. 别名配置 (alias):为常用目录设置别名,简化导入路径
// 2. 扩展名解析:配置哪些扩展名会被自动解析
// 3. 主文件解析:指定解析模块时查找的主文件名
resolve: {
// 别名配置 (alias)
alias: [
{
find: '@',
replacement: resolve(__dirname, './src'),
},
],
},
css: {
// 指定传递给 CSS 预处理器的选项。文件扩展名用作选项的键。每个预处理器支持的选项可以在它们各自的文档中找到
preprocessorOptions: {
// less 预处理器配置项
// 由于 Vite 的目标仅为现代浏览器,因此建议使用原生 CSS 变量来编写简单的、符合标准的 CSS。
// 话虽如此,但 Vite 也同时提供了对 `.scss`,`.sass`,`.less`,`.styl` 和 `.stylus` 文件的内置支持。
// 没有必要为它们安装特定的 Vite 插件,但必须安装相应的预处理器依赖(pnpm add -D less)
// 如果使用的是单文件组件,可以通过 **<style lang="less">**(或其他预处理器)自动开启
less: {
// 启用 Less 中的 JavaScript 表达式功能
javascriptEnabled: true,
// 可用于覆盖 Less 变量,目前为空对象
modifyVars: {},
// 如果启用,可以全局导入 Less 变量文件
// additionalData: ` @import '@/styles/variables.less';`
},
},
},
// 开发服务器选项
server: {
// 类型: string | boolean
// 默认: 'localhost'
// 指定服务器应该监听哪个 IP 地址。 如果将此设置为 0.0.0.0 或者 true 将监听所有地址,包括局域网和公网地址。
host: '0.0.0.0',
// 类型: number
// 默认值: 5173
// 指定开发服务器端口。注意:如果端口已经被使用,Vite 会自动尝试下一个可用的端口,所以这可能不是开发服务器最终监听的实际端口
port: 8088,
// 类型: boolean | string
// 开发服务器启动时,自动在浏览器中打开应用程序
open: true,
// 禁用或配置 HMR 连接(用于 HMR websocket 必须使用不同的 http 服务器地址的情况)
// 设置 server.hmr.overlay 为 false 可以禁用开发服务器错误的屏蔽
// hmr: {
// overlay: false,
// },
// 为开发服务器配置自定义代理规则
// 期望接收一个 { key: options } 对象。任何以 key 值开头的请求将被代理到对应的目标。如果 key 值以 ^ 开头,将被识别为 RegExp。
proxy: {
// '^/api': {
// target: 'https://nest-admin.buqiyuan.top',
// secure: false,
// agent: new https.Agent(),
// changeOrigin: true,
// rewrite: path => path.replace(/^\/api/, ''),
// },
},
// 提前转换和缓存文件以进行预热。可以在服务器启动时提高初始页面加载速度,并防止转换瀑布。
// 这是一个优化开发环境启动速度的配置项,它允许在服务器启动时提前转换和缓存指定的文件。这样做的好处包括:
// 1. 提高初始页面加载速度:预热的文件在首次访问时已经转换完成,无需等待即时转换
// 2. 防止转换瀑布:避免在页面加载时同时进行大量文件转换造成的阻塞
// 3. 改善开发体验:减少开发过程中因文件转换导致的延迟
warmup: {
// 请注意,只应该预热频繁使用的文件,以免在启动时过载 Vite 开发服务器
// 可以通过运行 npx vite --debug transform 并检查日志来找到频繁使用的文件
// clientFiles 是仅在客户端使用的文件
clientFiles: ['./index.html', './src/{components,api}/*'],
},
},
// 有时候默认的依赖启发式算法(discovery heuristics)可能并不总是理想的。如果您想要明确地包含或排除依赖项,可以使用 optimizeDeps 来进行设置。
// optimizeDeps.include 或 optimizeDeps.exclude 的一个典型使用场景,是当 Vite 在源码中无法直接发现 import 的时候。例如,import 可能是插件转换的结果。这意味着 Vite 无法在初始扫描时发现 import —— 只能在文件被浏览器请求并转换后才能发现。这将导致服务器在启动后立即重新打包
// include 和 exclude 都可以用来处理这个问题。如果依赖项很大(包含很多内部模块)或者是 CommonJS,那么你应该包含它;如果依赖项很小,并且已经是有效的 ESM,则可以排除它,让浏览器直接加载它
// 这个选项用于明确指定需要预构建的依赖项
// 通常Vite会自动发现和预构建依赖项,但某些依赖项可能需要显式声明
// 预构建可以提高冷启动速度,避免在页面加载时进行即时转换
optimizeDeps: {
include: ['lodash-es', 'ant-design-vue/es/locale/zh_CN', 'ant-design-vue/es/locale/en_US'],
},
// 构建过程可以通过多种 构建配置选项 来自定义构建。具体来说,你可以通过 `build.rollupOptions` 直接调整底层的 Rollup 选项
build: {
// 类型: boolean | 'terser' | 'esbuild'
// 默认: 客户端构建默认为 'esbuild',SSR构建默认为 false
// 设置为 `false` 可以禁用最小化混淆,或是用来指定使用哪种混淆器。默认为 esbuild,它比 terser 快 20-40 倍,压缩率只差 1%-2%。
minify: 'esbuild',
// 类型: `string | string[]`
// 默认值:'baseline-widely-available'
// 此选项允许用户为 CSS 的压缩设置一个不同的浏览器 target,此处的 target 并非是用于 JavaScript 转写目标。
// 应只在针对非主流浏览器时使用。 最直观的示例是当你要兼容的场景是安卓微信中的 webview 时,它支持大多数现代的 JavaScript 功能
// 但并不支持 CSS 中的 `#RGBA` 十六进制颜色符号,这种情况下,你需要将 `build.cssTarget` 设置为 `chrome61`,以防止 vite 将 `rgba()` 颜色转化为 `#RGBA` 十六进制符号的形式
cssTarget: 'chrome108',
// 类型: number
// 默认: 500
// 规定触发警告的 chunk 大小。(以 kB 为单位)。它将与未压缩的 chunk 大小进行比较;
// 设置生成的 chunk 文件大小警告阈值,单位为 KB,当 chunk 大小超过此限制时,Vite 会发出警告
// 这个配置只会影响构建过程中的警告信息,不会影响实际的功能或性能。如果你需要进一步优化构建产物的大小,可以考虑代码分割、懒加载等技术。
chunkSizeWarningLimit: 2000,
// 自定义底层的 Rollup 打包配置。这与从 Rollup 配置文件导出的选项相同,并将与 Vite 的内部 Rollup 选项合并
rollupOptions: {
// 配置 Rollup 的输出行为,可以控制生成的 chunk 和 asset 的各种属性,常见的配置项包括:
// 1. entryFileNames: 入口文件名格式
// 2. chunkFileNames: 代码分割的 chunk 文件名格式
// 3. assetFileNames: 静态资源文件名格式
// 4. manualChunks: 手动控制代码分割
// 5. format: 输出格式(如 es, cjs, iife 等)
// 6. minifyInternalExports:该选项值为 true,这意味着 Rollup 会尝试把内部变量导出为单个字母的变量,以便更好地压缩代码
output: {
// minifyInternalExports: false,
},
// 一个函数,用于拦截警告信息
onwarn(warning, rollupWarn) {
// 忽略循环依赖警告
if (warning.code === 'CYCLIC_CROSS_CHUNK_REEXPORT') {
return
}
rollupWarn(warning)
},
},
},
// esbuild 是一个极速的 JavaScript 打包工具和压缩器,Vite 使用它来进行代码转换和压缩。在项目中,esbuild 配置主要用于:
// 1. 代码压缩:项目配置了 build.minify: 'esbuild',表示使用 esbuild 进行代码压缩
// 2. 代码清理:通过 pure 和 drop 选项来移除特定代码
// 3. 特性支持:通过 supported 选项来指定支持的 JavaScript 特性
esbuild: {
// 标记函数调用为"纯函数"(pure functions),当这些函数的返回值未被使用时,esbuild 可以在压缩代码时安全地移除它们,主要用于移除像 console.log 这样的调试函数调用
// 当环境变量 VITE_DROP_CONSOLE 为 'true' 时,将 console.log 标记为纯函数,
// 在生产构建中,未被使用的 console.log 会被移除,从而减小打包体积
pure: VITE_DROP_CONSOLE === 'true' ? ['console.log'] : [],
// 直接移除指定类型的语句,在压缩过程中直接删除匹配的语句,不考虑其是否被使用,主要用于移除 debugger 语句或其他特定类型的代码
// 当环境变量 VITE_DROP_CONSOLE 为 'true' 时,在生产构建中移除所有 debugger 语句
// 这有助于减少生产环境中的调试代码
drop: VITE_DROP_CONSOLE === 'true' ? ['debugger'] : [],
// 明确指定支持顶级 await (Top-level await) 特性
// 这确保项目可以使用顶级 await 语法而无需额外的转换
supported: {
// https://github.com/vitejs/vite/pull/8665
'top-level-await': true,
},
},
}
})
注意1:CSS 预处理器
由于 Vite 的目标仅为现代浏览器,因此建议使用原生 CSS 变量来编写简单的、符合标准的 CSS。
话虽如此,但 Vite 也同时提供了对 .scss
,.sass
,.less
,.styl
和 .stylus
文件的内置支持。
没有必要为它们安装特定的 Vite 插件,但 必须安装相应的预处理器依赖
pnpm add -D less
如果使用的是单文件组件,可以通过 <style lang="sass">(或其他预处理器)自动开启
注意2:安装插件 @vitejs/plugin-vue-jsx
// 提供 Vue 3 JSX 支持
pnpm add @vitejs/plugin-vue-jsx --save-dev
注意3:在 define 配置项中用到的 dayjs 这个库,因此需要安装 dayjs 依赖
pnpm add dayjs