AI 驱动的 Vue3 应用开发平台 深入探究(二十):CLI与工具链之构建配置与Vite集成

1 阅读7分钟

构建配置与 Vite 集成

VTJ 提供了一个基于 Vite 构建的先进构建系统,它在不同项目类型之间提供统一的配置,同时保留了自定义的灵活性。构建架构与 monorepo 结构无缝集成,支持 Web 应用、uniapp 项目、扩展和组件库。

构建架构概览

VTJ 构建系统以 @vtj/cli 包为中心,该包导出了核心的 createViteConfig 函数。该函数提供了一个标准化的 Vite 配置层,抽象了常见的构建复杂性,同时通过插件架构和配置选项允许广泛的自定义。

Monorepo 使用 pnpm workspaces 结合 Lerna 来管理多个包和应用。工作区包括包、平台、应用和开发环境,它们共享一致的构建配置,同时保持独立的构建目标。

flowchart TD
    subgraph MonorepoRoot[Monorepo Root]
        A[pnpm-workspace.yaml]
        B[packages/*]
        C[platforms/*]
        D[apps/*]
        E[create-vtj]
        F[dev]
    end

    subgraph CoreBuildSystem[Core Build System]
        G["@vtj/cli package"]
        H[createViteConfig]
        I[createUniappViteConfig]
        J[createPluginViteConfig]
        K[Custom Plugins]
    end

    subgraph BuildTargets[Build Targets]
        L[Web Applications]
        M[Uniapp Projects]
        N[Library Packages]
        O[Extensions]
        P[Plugins]
    end

    A --> G
    B --> G
    C --> G
    D --> G
    E --> G
    F --> G

    G --> H
    G --> I
    G --> J
    G --> K

    H --> L
    H --> N
    H --> O
    H --> P
    I --> M
    K --> L
    K --> M
    K --> N
    K --> O
    K --> P
    J --> P

核心配置 API

createViteConfig 选项

createViteConfig 函数接受一个全面的选项对象,用于控制构建过程的各个方面。配置与合理的默认值合并,允许你仅覆盖必要的部分。

类别选项类型默认值描述备注
Serverportnumber9527开发服务器端口-
previewPortnumber3010预览服务器端口-
hoststring'0.0.0.0'服务器主机名
httpsbooleanfalse启用 HTTPS-
proxyProxyConfigundefined开发代理配置-
openbooleanundefined自动打开浏览器-
Buildlibbooleanfalse库模式-
outDirstring'dist'输出目录-
emptyOutDirbooleantrue清空输出目录-
buildTargetstringesnextES 目标版本-
manualChunksFunctionauto自定义代码分割-
Libraryentrystring'src/index.ts'入口文件-
formatsstring[]['es', 'cjs']输出格式-
externalstring[][]外部依赖-
externalGlobalsRecordundefined外部依赖的全局变量-
dtsbooleantrue生成 TypeScript 声明文件-
DevelopmentelementPlusbooleanfalseElement Plus 自动导入-
babelbooleanfalse启用 Babel 转译-
legacybooleanfalse旧版浏览器支持-
polyfillsbooleanstring[]trueNode.js polyfills
nodebooleanPolyfillOptionsundefinedNode polyfills 配置
PluginspluginsPluginOption[][]自定义 Vite 插件-
staticDirsstring[]StaticPluginOption[][]静态文件目录
copyStaticbooleanfalse构建时复制静态文件-
AdvancedaliasRecord<string, string>undefined路径别名-
optimizeDepsstring[]undefined预构建依赖-
visualizerbooleanfalse打包分析-
cdnCdnPluginOptionsundefinedCDN 导入配置-
defineConfigFunctionundefined自定义配置转换器-

环境配置

VTJ 通过 envPlugin 支持基于环境的配置。该插件根据 ENV_TYPE 环境变量自动加载配置,该变量可以是:localdevsituatprelive 之一。

环境文件应命名为 env.{type}.json 并从可配置的目录中加载。该插件将环境变量注入到 process.env 中,并通过 TypeScript 提供类型安全的访问。

应用构建配置

Web 应用

Web 应用使用标准的 createViteConfig 并配有典型的 Web 专用设置。该配置包括开发服务器设置、代理配置和浏览器部署优化。

// vite.config.ts
import { createViteConfig } from "@vtj/cli";
import { createDevTools } from "@vtj/local";
import proxy from "./proxy.config";

export default createViteConfig({
  proxy,
  base: "./",
  elementPlus: false,
  dts: false,
  optimizeDeps: [
    "monaco-editor",
    "monaco-editor/esm/vs/editor/editor.worker",
    "monaco-editor/esm/vs/language/json/json.worker",
  ],
  plugins: [
    createDevTools({
      link: false,
      copy: true,
      devMode: true,
    }),
  ],
  staticDirs: [
    {
      path: "/__devtools__/",
      dir: "../../node_modules/vite-plugin-vue-devtools/client",
    },
  ],
  copyStatic: true,
});

多页应用

VTJ 通过 pages 选项支持多页应用(MPA)配置。每个页面被定义为一个键值对,其中键成为入口名称,值指定 HTML 文件路径。

// 来自开发环境的多页配置
export default createViteConfig({
  pages: isUni
    ? {
        main: "uni/index.html",
      }
    : {
        main: "index.html",
      },
  // ... 其他选项
});

构建系统自动创建多个入口点并为每个页面生成相应的 HTML 文件。

库构建配置

库模式针对构建可复用组件和包进行了优化。它生成多种模块格式(ESM, CJS, UMD)并附带正确的 TypeScript 声明文件。

标准库构建

大多数 VTJ 包使用带有 TypeScript 声明的库模式:

{
  "scripts": {
    "build": "vue-tsc && vite build"
  }
}
// vite.config.ts (最小化配置)
export default defineConfig({
  build: {
    lib: {
      entry: "src/index.ts",
      name: "LibraryName",
      fileName: "index",
    },
    rollupOptions: {
      external: ["vue"],
      output: {
        globals: {
          vue: "Vue",
        },
      },
    },
  },
});

扩展构建

扩展构建为具有外部依赖的 UMD 库,以允许集成到现有项目中:

// 扩展配置
const globals = {
  vue: "Vue",
  "vue-router": "VueRouter",
  "element-plus": "ElementPlus",
  "@vueuse/core": "VueUse",
  "@vtj/pro": "__VTJ_PRO__",
  "@vtj/utils": "VtjUtils",
  "@vtj/icons": "VtjIcons",
  "@vtj/ui": "VtjUI",
  echarts: "echarts",
};

export default createViteConfig({
  lib: true,
  dts: true,
  library: "LibraryName",
  libFileName: "index",
  entry: "src/index.ts",
  formats: ["umd"],
  buildTarget: "es2015",
  external: Object.keys(globals),
  externalGlobals: globals,
});

此配置生成单个 UMD 文件,可通过 script 标签加载,所有依赖项预期在全局范围内可用。

Uniapp 构建配置

Uniapp 项目使用与 DCloudio 的 uni-app 构建系统集成的专用配置,同时保持 VTJ 的开发体验。

// Uniapp 配置
import { createViteConfig } from "@vtj/cli";
import { resolve } from "path";
import proxy from "./proxy.config";

const isDev = process.env.NODE_ENV !== "production";

export default createViteConfig({
  proxy,
  base: "./",
  outDir: "../pro/dist/uni",
  elementPlus: false,
  dts: false,
  loading: false,
  reload: false,
  port: 8010,
  alias: {
    vue: "@dcloudio/uni-h5-vue",
    "@vtj/uni": isDev ? resolve("../../packages/uni/src") : "@vtj/uni",
    "@vtj/renderer": isDev
      ? resolve("../../packages/renderer/src")
      : "@vtj/renderer",
  },
});

该配置使用 uni-app 特定的 Vue 实现,并为工作区包提供开发时的源码链接。

构建插件系统

VTJ 包含一个全面的插件生态系统,扩展了 Vite 在低代码开发工作流中的能力。

内置插件

插件用途配置
envPlugin环境变量注入envPath?: string
staticPlugin静态文件服务staticDirs: Array<string|StaticPluginOption>
copyPlugin构建时文件复制copyStatic?: boolean
versionPlugin版本文件生成version?: boolean
loadingPlugin加载页面生成loading?: boolean
reloadPluginHMR 增强reload?: boolean
cdnPluginCDN 导入cdn?: CdnPluginOptions
babelPluginBabel 转译babel?: boolean

插件根据配置选项通过 mergePlugins() 自动合并。

自定义插件集成

你可以通过 plugins 数组选项添加自定义插件:

import { createDevTools } from "@vtj/local";

export default createViteConfig({
  plugins: [
    createDevTools({
      link: false,
      copy: true,
      devMode: true,
      packagesDir: "../packages",
    }),
    // 在此处添加自定义插件
  ],
});

createDevTools 插件提供与 VTJ 开发工具的集成,包括物料的热模块替换和实时设计器更新。

构建流程工作流

flowchart TD
    Start[构建命令] --> Type{构建类型}
    Type -- 库 --> Lib[库模式]
    Type -- 应用 --> App[应用模式]
    Type -- 扩展 --> Ext[扩展模式]
    Type -- Uniapp --> Uni[Uniapp模式]

    Lib --> LoadEnv[加载 env.json]
    App --> LoadEnv
    Ext --> LoadEnv
    Uni --> LoadEnv

    LoadEnv --> CreateVite[创建 Vite 配置]
    CreateVite --> MergePlugins[合并插件]
    MergePlugins --> ApplyTransform[应用转换]
    ApplyTransform --> IsLib{库模式?}
    IsLib -- 是 --> ConfigRollup[配置 Rollup]
    IsLib -- 否 --> ConfigApp[配置应用构建]

    ConfigRollup --> External[外部依赖]
    ConfigApp --> Split[代码分割]

    External --> GenFormats[生成格式]
    Split --> GenFormats

    GenFormats --> TypeCheck[类型检查]
    TypeCheck --> GenDTS[生成 DTS]
    GenDTS --> BuildOutput[构建输出]

    BuildOutput --> CopyStatic{复制静态文件?}
    CopyStatic -- 是 --> Copy[复制资源]
    CopyStatic -- 否 --> Done[完成]
    Copy --> Done

代理配置

开发代理配置通过 proxy 选项处理,该选项接受 Vite 的标准代理配置格式。这通常从单独的 proxy.config.ts 文件导入。

// proxy.config.ts
export default {
  "/api": {
    target: "http://localhost:3000",
    changeOrigin: true,
    ws: true,
  },
};
// vite.config.ts
import proxy from "./proxy.config";

export default createViteConfig({
  proxy,
  // ... 其他选项
});

代理配置应用于开发服务器和预览服务器。

优化和代码分割

依赖优化

VTJ 为常见的大型包提供自动依赖优化:

optimizeDeps: [
  "monaco-editor",
  "monaco-editor/esm/vs/editor/editor.worker",
  "monaco-editor/esm/vs/language/json/json.worker",
  "monaco-editor/esm/vs/language/css/css.worker",
  "monaco-editor/esm/vs/language/html/html.worker",
  "monaco-editor/esm/vs/language/typescript/ts.worker",
];

这些依赖项被预构建以提高冷启动开发性能。

代码分割策略

构建系统包括针对 node_modules 的智能默认代码分割:

const P_MAP: Record<string, string> = {
  "async-validator": "shared",
  "lodash-unified": "shared",
  "memoize-one": "shared",
  "normalize-wheel-es": "shared",
  "regenerator-runtime": "shared",
  "dom-zindex": "shared",
  tslib: "shared",
  "@ctrl": "shared",
  "@popperjs": "shared",
  // ... 更多映射
};

你可以使用自定义的 manualChunks 函数覆盖此配置以实现细粒度控制。

Monorepo 构建管理

项目使用 Lerna 进行 monorepo 内的协调构建。关键构建命令:

{
  "scripts": {
    "build": "lerna run --no-private build",
    "cli:build": "cd packages/cli && npm run build",
    "dev:build": "cd dev && npm run build && npm run build:uni",
    "base:test": "cd packages/base && npm run vitest",
    "prerelease": "lerna version prerelease --yes && npm run build && npm run ci && pnpm -r publish --access public --tag test --no-git-checks && pnpm run sync"
  }
}

Lerna 处理版本管理、依赖图遍历和协调发布。

开发工作流

本地开发

对于本地开发,dev 脚本提供热重载环境:

npm run dev

# Uniapp 开发
npm run dev:uni

# 强制重新构建
vite --force

当使用 watchModules 配置时,开发环境会自动监视工作区包的更改。

构建输出

构建输出按格式组织:

包类型输出格式位置
核心包ESM, CJSdist/index.mjs, dist/index.cjs
UI 库ESM, CJS, UMDdist/index.mjs, dist/index.cjs, dist/index.umd.js
扩展UMDpublic/extension/index.umd.js
应用ES Modules带有哈希资源的 dist/

TypeScript 声明文件默认生成到 types/ 目录。

buildTarget 选项默认为 esnext 以获得最大的现代浏览器支持。当针对旧浏览器时,将 targetslegacy: true 结合使用,以启用 @vitejs/plugin-legacy 进行自动 polyfill 注入和回退生成。

对于库开发,请使用 lib: true 配合 external 以防止打包依赖项。这允许消费者使用他们自己版本的共享包(如 Vue),从而减少包体积和版本冲突。

下一步

现在你已了解 VTJ 的构建配置和 Vite 集成,你可以探索:

  • 自定义构建插件 — 了解如何为特定需求创建自定义构建插件
  • 开发与生产工作流 — 了解完整的开发生命周期和部署策略
  • 引擎架构概览 — 深入研究构建系统如何与整体 VTJ 架构集成

如需实际应用,请查看 devplatforms 目录中的配置示例。

参考资料