构建配置与 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 函数接受一个全面的选项对象,用于控制构建过程的各个方面。配置与合理的默认值合并,允许你仅覆盖必要的部分。
| 类别 | 选项 | 类型 | 默认值 | 描述 | 备注 |
|---|---|---|---|---|---|
| Server | port | number | 9527 | 开发服务器端口 | - |
| previewPort | number | 3010 | 预览服务器端口 | - | |
| host | string | '0.0.0.0' | 服务器主机名 | ||
| https | boolean | false | 启用 HTTPS | - | |
| proxy | ProxyConfig | undefined | 开发代理配置 | - | |
| open | boolean | undefined | 自动打开浏览器 | - | |
| Build | lib | boolean | false | 库模式 | - |
| outDir | string | 'dist' | 输出目录 | - | |
| emptyOutDir | boolean | true | 清空输出目录 | - | |
| buildTarget | string | esnext | ES 目标版本 | - | |
| manualChunks | Function | auto | 自定义代码分割 | - | |
| Library | entry | string | 'src/index.ts' | 入口文件 | - |
| formats | string[] | ['es', 'cjs'] | 输出格式 | - | |
| external | string[] | [] | 外部依赖 | - | |
| externalGlobals | Record | undefined | 外部依赖的全局变量 | - | |
| dts | boolean | true | 生成 TypeScript 声明文件 | - | |
| Development | elementPlus | boolean | false | Element Plus 自动导入 | - |
| babel | boolean | false | 启用 Babel 转译 | - | |
| legacy | boolean | false | 旧版浏览器支持 | - | |
| polyfills | boolean | string[] | true | Node.js polyfills | |
| node | boolean | PolyfillOptions | undefined | Node polyfills 配置 | |
| Plugins | plugins | PluginOption[] | [] | 自定义 Vite 插件 | - |
| staticDirs | string[] | StaticPluginOption[] | [] | 静态文件目录 | |
| copyStatic | boolean | false | 构建时复制静态文件 | - | |
| Advanced | alias | Record<string, string> | undefined | 路径别名 | - |
| optimizeDeps | string[] | undefined | 预构建依赖 | - | |
| visualizer | boolean | false | 打包分析 | - | |
| cdn | CdnPluginOptions | undefined | CDN 导入配置 | - | |
| defineConfig | Function | undefined | 自定义配置转换器 | - |
环境配置
VTJ 通过 envPlugin 支持基于环境的配置。该插件根据 ENV_TYPE 环境变量自动加载配置,该变量可以是:local、dev、sit、uat、pre 或 live 之一。
环境文件应命名为 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 |
| reloadPlugin | HMR 增强 | reload?: boolean |
| cdnPlugin | CDN 导入 | cdn?: CdnPluginOptions |
| babelPlugin | Babel 转译 | 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, CJS | dist/index.mjs, dist/index.cjs |
| UI 库 | ESM, CJS, UMD | dist/index.mjs, dist/index.cjs, dist/index.umd.js |
| 扩展 | UMD | public/extension/index.umd.js |
| 应用 | ES Modules | 带有哈希资源的 dist/ |
TypeScript 声明文件默认生成到 types/ 目录。
buildTarget选项默认为esnext以获得最大的现代浏览器支持。当针对旧浏览器时,将targets与legacy: true结合使用,以启用@vitejs/plugin-legacy进行自动 polyfill 注入和回退生成。
对于库开发,请使用
lib: true配合external以防止打包依赖项。这允许消费者使用他们自己版本的共享包(如 Vue),从而减少包体积和版本冲突。
下一步
现在你已了解 VTJ 的构建配置和 Vite 集成,你可以探索:
- 自定义构建插件 — 了解如何为特定需求创建自定义构建插件
- 开发与生产工作流 — 了解完整的开发生命周期和部署策略
- 引擎架构概览 — 深入研究构建系统如何与整体 VTJ 架构集成
如需实际应用,请查看 dev 和 platforms 目录中的配置示例。
参考资料
- 官方文档:vtj.pro/
- 在线平台:app.vtj.pro/
- 开源仓库:gitee.com/newgateway/…