构建优化:依赖预构建调优、代码分割、生产构建

本节目标

依赖预构建调优:默认 Vite 会自动探测并预构建依赖,但有些包需要你显式声明:

// vite.config.js
export default defineConfig({
  optimizeDeps: {
    include: ['lodash-es', 'axios'], // 明确要预构建的
    exclude: ['@scope/already-esm'], // 已是 ESM、无需预构建的
  },
})

代码分割:生产构建用 Rollup 的 manualChunks 把第三方库拆成独立 vendor chunk,提升缓存:

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          vendor: ['react', 'react-dom'], // 这些包打进 vendor.js
        },
      },
    },
    // 压缩器:'esbuild'(默认,快)或 'terser'(更彻底)
    minify: 'esbuild',
    target: 'es2020', // 输出语法的目标浏览器
  },
})
# 生产构建;产物在 dist/
# npm run build

Lib 模式(打包「库」而非「应用」):

export default defineConfig({
  build: {
    lib: {
      entry: 'src/index.ts',
      name: 'MyLib',
      fileName: 'my-lib',
      formats: ['es', 'umd'],
    },
    rollupOptions: {
      external: ['vue'], // 把 vue 标为外部依赖,不打进包
    },
  },
})

external 让「用户环境里已有」的包(如 vue)不进你的库产物,避免重复打包。

名词解释

manualChunks:Rollup 的代码分割配置,手动指定「哪些模块合并成一个 chunk」,常用于把第三方库拆成 vendor,利于长期缓存。

Lib 模式(build.lib):Vite 打包「可发布的库」的模式,产出 ESM/UMD 等多种格式,适合发 npm 包而非网页应用。

external:声明「这些依赖不打进产物」,由使用者自行提供。发库时必须把 peer 依赖(如框架)标 external。

minify:压缩器选项。esbuild(默认,快)或 terser(更优体积,更慢)。

课后练习

练习 1:optimizeDeps.include 和 build.rollupOptions.manualChunks 分别在哪个阶段起作用?

答案:optimizeDeps.include 作用于开发预构建(让依赖变成 ESM 缓存);manualChunks 作用于生产构建(控制产物如何拆 chunk)。两者阶段不同、目的不同,不要混淆。

练习 2:发一个 Vue 组件库时,为什么要把 vue 设为 external?

答案:因为使用你库的项目自己已经装了 vue。若把 vue 打进你的库,会出现「两份 vue」导致实例不共享、体积翻倍。标 external 让库「假定宿主环境提供 vue」,只发布你自己的代码。

总结

Vite 优化三件事:optimizeDeps 调好开发预构建、manualChunks 拆好生产 vendor、lib 模式 + external 发好库。它们分别落在「开发」「构建」「发库」三个场景,互不干扰。记住 Vite 的哲学——「开发极简、构建交给 Rollup 深挖」——优化时顺着这条线找配置项就不会乱。最后一节我们做实战整合:接入框架、dev server 代理与部署。