第四张:配置 vite.config.ts 文件

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
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容