AI 驱动的 Vue3 应用开发平台 深入探究(二十二):CLI与工具链之开发与生产工作流

开发与生产工作流

本指南涵盖了 VTJ 的完整开发生命周期,从本地开发到生产部署。VTJ 采用了精密的 Monorepo 架构,结合 pnpm workspaces、Vite 构建系统以及自动化发布流水线,支持多种部署目标和平台。

工作流架构

VTJ 实施了一种分层开发方法,将包开发与应用部署分离开来。该架构通过统一的 CLI 系统,同时支持库包和生产应用。

graph TD subgraph Release H[版本升级] --> I[Lerna构建] I --> J[包发布] J --> K[镜像同步] end subgraph Development A[本地开发] --> B[测试] B --> C[构建包] C --> D[本地预览] end subgraph Production E[环境构建] --> F[多平台输出] F --> G[部署] end C --> E D -.-> E

该工作流集成了三个不同的阶段:具备热重载功能的活跃开发、跨多环境的生产构建,以及自动发布到 npm 注册表。

本地开发工作流

VTJ 的本地开发采用基于目标的方法,开发者可以专注于特定的包、平台或演示应用。

启动开发服务器

根目录的 package.json 提供了针对不同开发场景的便捷脚本:

命令 目标 用途 端口
npm run dev dev 目录 主设计器开发 9527
npm run dev:uni dev 目录 UniApp 平台开发 9527
npm run pro:dev platforms/pro 生产平台 IDE 9527
npm run pro-uni:dev platforms/pro-uni UniApp 生产平台 9527
npm run app:dev apps/app Web 应用示例 9527
npm run h5:dev apps/h5 H5 移动端应用 9527

开发服务器默认使用启用了热模块替换(HMR)的 Vite。CLI 的 createServer 函数配置了 CORS、端口绑定(默认为 9527)以及用于 API 模拟的可选代理配置。

💡 默认开发端口(9527)定义在 CLI 的 defaults.ts 配置中。你可以通过特定环境的代理配置覆盖它,或者向 createViteConfig 传递自定义端口设置。

开发环境配置

VTJ 通过 JSON 文件使用基于环境的配置:

scss 复制代码
env.json (默认配置)
├── env.local.json (本地开发)
├── env.dev.json (开发环境)
├── env.sit.json (系统集成测试)
├── env.uat.json (用户验收测试)
├── env.pre.json (预生产)
└── env.live.json (生产环境)

CLI 的 getConfig 函数将基础配置与特定环境的覆盖配置合并:

typescript 复制代码
export function getConfig(envPath: string, type: string): Record<string, any> {
  const defaults = resolve(envPath, "env.json");
  const env = resolve(envPath, `env.${type}.json`);
  const defaultConfig = pathExistsSync(defaults) ? readJsonSync(defaults) : {};
  const envConfig = pathExistsSync(env) ? readJsonSync(env) : {};
  return Object.assign({}, defaultConfig, envConfig);
}

这种模式允许在不同环境之间无缝切换,无需更改代码------只需在构建期间切换 ENV_TYPE 环境变量。

测试工作流

测试通过 Vitest 集成到每个包中,并支持 DOM 测试的 jsdom 环境。

运行测试

VTJ 为每个包提供了细粒度的测试命令:

bash 复制代码
npm run core:test
npm run cli:test
npm run renderer:test

# 运行整个 monorepo 的所有测试
npm run test

每个包包含一个 vitest.config.ts 配置文件,用于设置 jsdom 作为测试环境:

typescript 复制代码
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    environment: "jsdom",
  },
});

Nx 依赖管理

Monorepo 使用 Nx 来编排具有依赖感知的测试执行。nx.json 配置确保测试按拓扑顺序运行:

json 复制代码
{
  "targetDefaults": {
    "test": {
      "dependsOn": ["^test"]
    }
  }
}

这意味着当测试 @vtj/renderer 时,Nx 会自动先测试依赖包(如 @vtj/core),从而确保隔离于依赖缺陷。

构建过程

VTJ 的构建系统区分了库包(通过 npm 分发)和应用(部署到服务器)。

库包构建

库包使用 @vtj/cli 的标准化构建配置。每个库的 vite.config.ts 委托给 createViteConfig,并传入特定库的选项:

typescript 复制代码
import { createViteConfig } from "@vtj/cli";

export default createViteConfig({
  lib: true,
  dts: true,
  version: true,
  formats: ["es", "cjs"],
  external: ["@vtj/base"],
});

构建过程生成:

  • ES 模块(.mjs),用于现代打包工具
  • CommonJS(.cjs),用于 Node.js 兼容性
  • TypeScript 声明(types/ 目录)

构建配置自动处理:

  • 通过 vue-tsc 进行 TypeScript 编译
  • 带有代码分割的 Rollup 打包
  • CSS 提取到独立文件
  • 外部依赖排除

应用构建

应用构建支持多环境目标,并进行特定于环境的编译:

命令 环境 输出 用例
npm run build:dev dev 开发构建 功能测试
npm run build:sit sit 集成构建 QA 测试
npm run build:uat uat UAT 构建 干系人测试
npm run build:pre pre 预生产 最终预演
npm run build:prod live 生产构建 正式上线

构建脚本模式遵循:cross-env ENV_TYPE=<type> vite build,该命令在构建过程中加载对应的 env.<type>.json 配置。

构建输出结构

Vite 的构建配置使用智能代码分割,定义于 packages/cli/src/vite/build.ts

typescript 复制代码
const defaultManualChunks = (id: string) => {
  if (id.includes("node_modules")) {
    const arr = id.split("node_modules/");
    const dirs = arr[arr.length - 1].split("/");
    const name = dirs[0];
    if (PACKAGES.includes(name)) {
      return name;
    }
    if (P_MAP[name]) {
      return P_MAP[name];
    }
    // ... 更多分块逻辑
  }
};

这会创建优化的打包文件,并将供应商块按以下分类分离:

  • 框架代码:Vue, VueRouter, VueDemi
  • UI 库:Element Plus, Vant
  • 工具库:Lodash, async-validator
  • 图表库:ECharts, ZRender

多平台部署

VTJ 支持从单一代码库部署到多个平台:Web(桌面/移动浏览器)、H5(移动 Web)和 UniApp(微信小程序、原生应用)。

graph TD A[源代码] --> B[构建过程] B --> C{平台目标} C --> D[Web构建] C --> E[H5构建] C --> F[UniApp构建] D --> G[静态资源] E --> G F --> H[UniApp包] G --> I[CDN/Web服务器] H --> J[小程序或应用商店]

特定平台构建命令

bash 复制代码
# Web 平台
npm run pro:build

# H5 移动端平台
npm run mui:build

# UniApp 平台(小程序)
npm run uniapp:mp

# 所有平台同时构建
npm run dev:build

UniApp 构建使用专门的 Vite 配置 createUniappViteConfig,其中包括 Node.js API 的 polyfills 和用于 uni-app 兼容性的特定别名配置。

发布与发布工作流

VTJ 使用 Lerna 进行自动化版本控制和发布,并结合 Conventional Commits 标准生成变更日志。

版本管理

发布过程遵循语义化版本控制,采用 Lerna 的独立版本模式 lerna.json

json 复制代码
{
  "version": "independent",
  "useNx": true,
  "npmClient": "pnpm"
}

这允许每个包维护自己的版本号,当更改提交到该特定包时独立递增。

发布脚本

命令 版本递增类型 动作
npm run patch 0.0.x 仅错误修复
npm run minor 0.x.0 新功能(向后兼容)
npm run prerelease 0.0.0-x 预发布版本

每个发布命令都会触发完整的流水线:

  1. Lerna 版本升级(创建 git 标签)
  2. 跨所有包的完整构建
  3. 提交带有发布信息的 git commit
  4. 发布到 npm 注册表
  5. 同步到镜像注册表

发布过程

发布阶段使用 pnpm 的工作区感知发布功能:

bash 复制代码
pnpm -r publish --access public --publish-branch next --report-summary --no-git-checks

关键发布特性:

  • 工作区感知:仅发布已更改的包
  • 公开访问:包公开可用
  • 分支定向 :发布到 next dist-tag 用于 Beta 版本
  • 提交验证:通过 commitlint 强制执行 Conventional Commit 格式

注册表同步

发布后,sync 脚本将包同步到 npm 镜像注册表,以便在某些区域更快访问:

javascript 复制代码
const modules = [
  "create-vtj",
  "@vtj/cli",
  "@vtj/utils",
  // ... 20+ 包
];

async function sendSync(name) {
  const res = await axios.put(
    `https://registry-direct.npmmirror.com/${name}/sync?sync_upstream=true`,
  );
  // 轮询同步状态直到完成
}

这确保包在发布后立即可用于 npmmirror.com 等镜像。

Monorepo 管理

VTJ 使用 pnpm workspaces 结合 Nx,以实现高效的构建编排和依赖管理。

工作区结构

工作区配置定义了包的位置 pnpm-workspace.yaml

yaml 复制代码
packages:
  - "packages/*" # 核心库包
  - "platforms/*" # 生产平台
  - "apps/*" # 示例应用
  - "create-vtj" # CLI 脚手架工具
  - "dev" # 开发环境
  - "docs" # 文档站点

依赖缓存

Nx 基于文件哈希和依赖图提供构建缓存 nx.json

json 复制代码
{
  "targetDefaults": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["{projectRoot}/dist", "{projectRoot}/types"]
    }
  }
}

这意味着:

  • 依赖项先构建(拓扑顺序)
  • 构建输出按输入哈希缓存
  • 未更改的包完全跳过重建

清理工作区

clean 脚本移除所有构建产物和锁文件,以便重新开始:

javascript 复制代码
const DIRS = ["lib", "cdn", "types", "dist", "coverage", "temp"];
const FILES = ["tsconfig.tsbuildinfo", "package-lock.json", "pnpm-lock.yaml"];

// 清理包、平台、应用和特殊目录
await cleanDir(await getPackages(PACKAGES_PATH), PACKAGES_PATH);
await cleanDir(await getPackages(PLATFORMS_PATH), PLATFORMS_PATH);
await cleanDir(await getPackages(APPS_PATH), APPS_PATH);

reset 命令提供完整的工作区重置:pnpm run clean && pnpm run setup

💡 当遇到依赖冲突或 node_modules 损坏时,请使用 reset 命令。这在切换到包版本差异显著的分支后特别有用。

使用 Create VTJ 进行项目脚手架搭建

create-vtj CLI 工具为各种用例提供项目模板,自动化设置带有预配置构建管道的新 VTJ 项目。

可用模板

bash 复制代码
npm create vtj@latest

可用模板包括:

  • app:功能齐全的 Web 应用,集成设计器
  • h5:移动端优化的 H5 应用
  • uniapp:基于 UniApp 的小程序或应用
  • library:组件或工具库
  • material:自定义物料组件库
  • plugin:设计器插件开发
  • extension:浏览器扩展

每个模板包括:

  • 预配置的 Vite 构建设置
  • 环境配置文件
  • 用于 API 模拟的代理配置
  • TypeScript 配置
  • 包依赖项

CLI 构建过程

create-vtj CLI 本身使用 unbuild 进行分发:

typescript 复制代码
export default defineBuildConfig({
  entries: ["src/index"],
  clean: true,
  declaration: true,
  rollup: {
    emitCJS: true,
    inlineDependencies: true,
  },
  outDir: "dist",
  stub: false,
});

这会生成带有内联依赖项的 ESM 和 CJS 格式,以便独立 CLI 执行。

故障排除

常见构建问题

问题 原因 解决方案
构建卡在依赖解析上 工作区循环依赖 检查 pnpm-workspace.yaml 并运行 pnpm install --force
构建后类型错误 缺少 TypeScript 声明 确保 Vite 配置中 dts: true 并重新构建
端口被占用 (9527) 之前的开发服务器仍在运行 终止进程或更改代理配置中的端口
导入解析错误 别名配置不正确 验证 Vite 别名路径与项目结构匹配

性能优化

为了在开发期间加快构建:

  1. 必要时使用 --force 标志绕过 Vite 缓存
  2. 启用 watchModules 以从文件监视中排除 node_modules
  3. 针对现代浏览器目标禁用旧版本构建
  4. 使用选择性包构建:npm run core:build 而不是完整的 monorepo 构建

依赖冲突

遇到版本冲突时:

  1. 运行 npm run clean 移除所有产物
  2. 运行 npm run reset 进行完整的工作区重置
  3. 运行 npm run update 将所有依赖项更新到最新的兼容版本

后续步骤

要深入了解 VTJ 的架构以及如何扩展系统:

  • 构建配置和 Vite 集成 - 学习高级构建定制和 Vite 插件开发
  • Create VTJ CLI 参考 - 掌握 CLI 工具和模板系统
  • 架构概述 - 了解整体系统设计和组件交互

对于实际实现指导:

  • 项目模板 - 开始使用特定的应用类型
  • 自定义构建插件 - 使用自定义 Vite 插件扩展构建系统

VTJ 中的开发工作流旨在提供从本地开发到生产部署的无缝体验,并为跨多个平台和环境的测试、构建和发布提供强大的工具支持。

参考资料

相关推荐
Ankkaya3 小时前
大师助我,electron-hiprint 源码梳理
前端·vue.js
风止何安啊3 小时前
🪝 别再重复造轮子了!教你偷懒:在 React 自定义 Hook
前端·react.js·面试
踩着两条虫3 小时前
AI 驱动的 Vue3 应用开发平台 深入探究(二十三):API与参考之Engine API 参考
前端·vue.js·ai编程
Moment3 小时前
开源一年,我的 AI 全栈项目 AI 协同编辑器终于有 1.1 k star了 😍😍😍
前端·后端·面试
爱学习的小囧3 小时前
VCF 集群部署灵活组合:单节点与高可用配置完全指南
java·服务器·前端
虎头金猫3 小时前
小米摄像头本地化存储教程:Go2RTC+EasyNVR 搭建私有监控系统
langchain·开源·github·aigc·智能家居·开源软件·ai编程
96773 小时前
AJAX和Axios理解和关系
前端·ajax·okhttp
sg_knight3 小时前
Claude Code 如何辅助定位 Bug 和问题代码
java·前端·bug·ai编程·claude·code·claude-code
行思理3 小时前
Linux查看网站访问IP的命令大全
linux·服务器·前端