Skip to content
On this page

Vite 构建

Vite 的构建功能用于将项目打包成适合生产环境的静态资源。Vite 使用 Rollup 进行生产构建,提供了高效的打包和优化功能。

构建命令

运行以下命令进行生产构建:

bash
npm run build

这将根据 vite.config.js 中的配置创建一个优化过的构建输出,默认输出到 dist 目录。

构建配置

基本构建选项

javascript
// vite.config.js
export default {
  build: {
    outDir: 'dist',           // 输出目录
    assetsDir: 'assets',      // 静态资源目录
    assetsInlineLimit: 4096,  // 小于该值的资源将内联为 base64
    cssCodeSplit: true,       // 启用 CSS 代码分割
    sourcemap: false,         // 是否生成 sourcemap
    minify: 'esbuild',        // 压缩方式: 'esbuild', 'terser', 或 false
    target: 'modules',        // 浏览器目标
    cssTarget: 'chrome61',    // CSS 兼容目标
  }
}

输出目录配置

javascript
// vite.config.js
export default {
  build: {
    outDir: 'my-build',       // 自定义输出目录
    assetsDir: 'static'       // 自定义静态资源目录
  }
}

构建后目录结构:

dist/
├── assets/
│   ├── index.123456.js
│   ├── index.123456.css
│   └── image.789abc.png
├── index.html
└── favicon.ico

压缩配置

Vite 支持两种压缩方式:

javascript
// vite.config.js
export default {
  build: {
    // 使用 esbuild 压缩(默认,更快)
    minify: 'esbuild',
    
    // 或使用 terser 压缩(更小的包,但更慢)
    minify: 'terser',
    
    // 或禁用压缩
    minify: false
  }
}

Terser 配置

当使用 terser 时,可以进一步配置:

javascript
// vite.config.js
export default {
  build: {
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,  // 删除 console
        drop_debugger: true  // 删除 debugger
      },
      mangle: true
    }
  }
}

Rollup 选项

Vite 构建基于 Rollup,可以传递额外的 Rollup 选项:

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      // 外部化依赖以避免打包
      external: ['vue', 'react'],
      
      output: {
        // 为外部依赖提供全局变量
        globals: {
          vue: 'Vue',
          react: 'React'
        },
        
        // 自定义 chunk 文件名
        chunkFileNames: 'assets/js/[name]-[hash].js',
        entryFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
      }
    }
  }
}

代码分割

自动代码分割

Vite 会自动进行代码分割:

javascript
// 动态导入实现代码分割
const { debounce } = await import('lodash-es')

// 或使用 import() 语法
const module = await import(`./modules/${moduleName}.js`)

手动代码分割

通过 Rollup 配置实现更精细的代码分割:

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['vue', 'vue-router'],
          utils: ['lodash-es', 'axios']
        }
      }
    }
  }
}

或者使用函数形式:

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            if (id.includes('vue')) {
              return 'vendor-vue'
            }
            return 'vendor'
          }
        }
      }
    }
  }
}

资源处理

静态资源

Vite 会自动处理静态资源:

javascript
// 在 JS 中导入资源
import imgUrl from './assets/image.png'
const img = document.createElement('img')
img.src = imgUrl

// 或在 CSS 中
background-image: url('./assets/bg.jpg');

资源内联限制

javascript
// vite.config.js
export default {
  build: {
    assetsInlineLimit: 4096  // 小于 4KB 的资源将内联为 base64
  }
}

公共目录

public 目录中的文件会直接复制到输出目录根部:

public/
├── favicon.ico
├── robots.txt
└── manifest.json

CSS 处理

CSS 代码分割

javascript
// vite.config.js
export default {
  build: {
    cssCodeSplit: true  // 启用 CSS 代码分割(默认)
  }
}

CSS 压缩

javascript
// vite.config.js
export default {
  build: {
    cssMinify: 'esbuild'  // CSS 压缩方式: 'esbuild', 'lightningcss'
  }
}

预加载和预获取

Vite 会自动生成资源预加载指令:

<!-- 构建后自动生成 -->
<link rel="modulepreload" href="/assets/index.123456.js">

您也可以手动控制:

javascript
// vite.config.js
export default {
  build: {
    rollupOptions: {
      output: {
        // 控制预加载行为
        format: 'es',
        hoistTransitiveImports: false
      }
    }
  }
}

构建模式

不同环境构建

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig(({ mode }) => {
  return {
    build: {
      outDir: mode === 'production' ? 'dist' : 'dev-dist'
    }
  }
})

条件构建

// vite.config.js
export default {
  build: {
    // 只在生产环境构建时启用某些选项
    minify: process.env.NODE_ENV === 'production' ? 'terser' : false,
    sourcemap: process.env.NODE_ENV !== 'production'
  }
}

构建分析

包分析

使用 rollup-plugin-visualizer 分析包大小:

npm install rollup-plugin-visualizer -D
javascript
// vite.config.js
import { visualizer } from 'rollup-plugin-visualizer'

export default {
  plugins: [
    process.env.ANALYZE && visualizer({
      filename: 'dist/stats.html',
      open: true
    })
  ].filter(Boolean)
}

运行分析:

bash
ANALYZE=1 npm run build

高级构建配置

多页面应用

// vite.config.js
import { resolve } from 'path'

export default {
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'index.html'),
        nested: resolve(__dirname, 'nested/index.html')
      }
    }
  }
}

库模式

构建库而不是应用程序:

// vite.config.js
export default {
  build: {
    lib: {
      entry: resolve(__dirname, 'lib/main.js'),
      name: 'MyLib',
      fileName: (format) => `my-lib.${format}.js`
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
}

SSR 构建

服务端渲染构建:

// vite.config.js
export default {
  build: {
    ssr: true,
    outDir: 'dist/server'
  }
}

构建钩子

在构建过程中使用插件钩子:

// vite.config.js
export default {
  plugins: [
    {
      name: 'build-hooks',
      buildStart() {
        console.log('构建开始')
      },
      renderChunk(code, chunk, opts) {
        // 修改生成的代码块
      },
      generateBundle(options, bundle) {
        // 操作生成的包
        console.log('Bundle keys:', Object.keys(bundle))
      },
      writeBundle() {
        console.log('构建完成')
      }
    }
  ]
}

常见构建问题

包过大

  • 检查是否意外打包了开发依赖
  • 使用动态导入实现代码分割
  • 分析包内容找出大体积依赖

构建时间过长

  • 减少不必要的插件
  • 优化代码分割
  • 使用更快的压缩方式(esbuild)

环境变量问题

  • 确保生产环境变量正确加载
  • 使用 VITE_ 前缀的环境变量

通过合理配置构建选项,您可以优化应用的性能、加载速度和用户体验,让应用在生产环境中表现最佳。