构建系统与分发
本文档描述了 relation-graph 的 monorepo 构建系统、包结构以及分发策略。它涵盖共享核心与各平台专用包如何构建、打包并发布到 npm。
有关多平台架构以及各框架专用组件如何与核心集成的信息,请参阅 多平台架构。
Monorepo 结构
relation-graph 仓库以 monorepo 形式组织,包含一个共享核心与五个面向不同平台的 npm 包。每个平台包提供框架专用绑定,同时共享相同的底层核心实现。
graph TB
Root["根目录
package.json"]
BuildScript["build-all.sh
构建编排"]
subgraph "平台包"
Vue3Pkg["@relation-graph/vue
platforms/vue3/package.json"]
Vue2Pkg["@relation-graph/vue2
platforms/vue2/package.json"]
ReactPkg["@relation-graph/react
platforms/react/package.json"]
SveltePkg["@relation-graph/svelte
platforms/svelte/package.json"]
WebCompPkg["@relation-graph/web-components
platforms/web-components/package.json"]
end
subgraph "共享依赖"
DevDeps["开发依赖
TypeScript, ESLint, Prettier"]
TSConfig["TypeScript 配置
在各包之间共享"]
end
Root -->|调用| BuildScript
BuildScript -->|构建| Vue3Pkg
BuildScript -->|构建| Vue2Pkg
BuildScript -->|构建| ReactPkg
BuildScript -->|构建| SveltePkg
BuildScript -->|构建| WebCompPkg
Vue3Pkg -.->|使用| DevDeps
Vue2Pkg -.->|使用| DevDeps
ReactPkg -.->|使用| DevDeps
SveltePkg -.->|使用| DevDeps
WebCompPkg -.->|使用| DevDeps
Vue3Pkg -.->|使用| TSConfig
Vue2Pkg -.->|使用| TSConfig
ReactPkg -.->|使用| TSConfig
SveltePkg -.->|使用| TSConfig
WebCompPkg -.->|使用| TSConfig根包配置
根目录的 package.json 充当 monorepo 的编排器,并为所有平台提供单一构建命令:
| 字段 | 值 | 用途 |
|---|---|---|
name |
relation-graph |
根包名称 |
version |
3.0.3 |
跨所有包同步的版本 |
private |
false |
允许发布子包 |
scripts.build-all |
sh ./build-all.sh |
构建所有平台包 |
根包还定义了所有平台共用的开发依赖:
- TypeScript 编译器(
typescript: ^4.7.4) - ESLint 以及用于 Vue、React 与 TypeScript 的插件
- 用于代码格式化的 Prettier
- 类型定义(
@types/node)
构建系统架构
构建系统遵循基于 shell 脚本的编排模式,由单个脚本协调构建所有平台包。
graph LR
Developer["开发者"]
BuildAll["build-all.sh"]
subgraph "每个平台的构建步骤"
TypeScript["TypeScript 编译
tsc"]
Bundler["模块打包
UMD + ESM"]
TypeGen["类型定义生成
.d.ts files"]
end
subgraph "构建输出"
UMD["relation-graph.umd.js
通用模块定义"]
ESM["relation-graph.mjs
ES Module"]
Types["types/packages/platforms/[platform]/src/index.d.ts
TypeScript 定义"]
end
Developer -->|npm run build-all| BuildAll
BuildAll --> TypeScript
TypeScript --> Bundler
TypeScript --> TypeGen
Bundler --> UMD
Bundler --> ESM
TypeGen --> Types构建编排脚本
根包中引用的 build-all.sh 脚本负责协调五个平台包的构建流程。该脚本可能会:
- 将 TypeScript 源文件编译为 JavaScript
- 将代码打包为 UMD 与 ESM 格式
- 生成 TypeScript 声明文件
- 复制资源与样式
- 为每个平台包准备 npm 发布所需内容
包输出结构
每个平台包会生成三个主要输出产物,以支持不同的使用方式:
graph TB
Package["平台包
例如:@relation-graph/react"]
subgraph "输出产物"
UMD["relation-graph.umd.js
package.json: main, unpkg"]
ESM["relation-graph.mjs
package.json: module"]
Types["types/packages/platforms/[platform]/src/index.d.ts
package.json: types"]
end
subgraph "消费方式"
Script["Script 标签
CDN/unpkg"]
ModernBuild["现代构建工具
Webpack, Vite, Rollup"]
TypeScriptIDE["TypeScript/IDE
智能提示"]
end
Package --> UMD
Package --> ESM
Package --> Types
UMD --> Script
ESM --> ModernBuild
Types --> TypeScriptIDEUMD 格式(Universal Module Definition)
relation-graph.umd.js 文件提供一个可在多种环境下工作的通用模块:
- 浏览器全局变量:可通过
<script>标签加载,暴露一个全局变量 - AMD 模块:兼容 RequireJS
- CommonJS:可用于 Node.js 的
require() - CDN 分发:由
unpkg字段引用,适用于 unpkg.com 等服务
main 与 unpkg 字段都指向该产物,使其成为传统打包器与 CDN 用法的默认选择。
ESM 格式(ES Modules)
relation-graph.mjs 文件提供原生 ES 模块格式:
- 支持 Tree-shaking:现代打包器可以移除未使用的代码
- 静态导入:使用
import/export语法 - 模块优化:更适合使用 Webpack、Rollup 或 Vite 进行生产构建
module 字段指向该产物,使现代打包器优先使用 ESM 而非 UMD。
TypeScript 声明文件
TypeScript 声明文件为 IDE 与 TypeScript 项目提供类型信息:
types/packages/platforms/[platform]/src/index.d.ts
各平台的 types 路径结构不同:
| 平台 | Types 路径 |
|---|---|
| Vue 3 | ./types/packages/platforms/vue3/src/index.d.ts |
| Vue 2 | ./types/packages/platforms/vue2/src/index.d.ts |
| React | ./types/packages/platforms/react/src/index.d.ts |
| Svelte | ./types/packages/platforms/svelte/src/index.d.ts |
| Web Components | ./types/packages/platforms/svelte/src/index.d.ts(注:看起来引用了 svelte) |
集中式的 types/ 目录暗示存在一个统一的 TypeScript 编译步骤,用于为所有平台生成声明文件。
平台包配置
每个平台包都遵循一致的结构,并包含平台专用元数据。
通用包字段
所有平台包共享如下配置:
| 字段 | 值 | 描述 |
|---|---|---|
version |
3.0.3 |
在所有包之间同步 |
license |
MIT |
开源许可证 |
author |
WanLian <seeksdream@qq.com> |
包维护者 |
repository.url |
git+https://github.com/seeksdream/relation-graph.git |
GitHub 仓库 |
homepage |
http://relation-graph.com |
文档网站 |
平台专用包名
每个包都在 @relation-graph 组织下使用 scope 名称:
graph TB
Org["@relation-graph
npm 组织"]
Org --> Vue3["@relation-graph/vue
Vue 3 支持"]
Org --> Vue2["@relation-graph/vue2
Vue 2 支持"]
Org --> React["@relation-graph/react
React 支持"]
Org --> Svelte["@relation-graph/svelte
Svelte 支持"]
Org --> WebComp["@relation-graph/web-components
与框架无关"]
subgraph "使用示例"
VueInstall["npm install @relation-graph/vue"]
ReactInstall["npm install @relation-graph/react"]
SvelteInstall["npm install @relation-graph/svelte"]
end
Vue3 -.-> VueInstall
React -.-> ReactInstall
Svelte -.-> SvelteInstall关键词与 SEO
每个包都包含大量关键词以提升在 npm 搜索中的可发现性。关键词与平台相关,包含英文与中文术语:
Vue 3 包关键词:
relation-graph vue versionvue relationship graphvue knowledge graphvue 关系图谱(中文:relationship graph)vue 知识图谱(中文:knowledge graph)
React 包关键词:
relation-graph react versionreact relationship graphreact graph editorreact 图谱编辑器(中文:graph editor)
开发依赖
所有平台包共享完全相同的开发依赖,并在根目录统一管理:
graph TB
subgraph "TypeScript 工具链"
TS["typescript: ^4.7.4"]
TSTypes["@types/node: *"]
TSESLint["@typescript-eslint/eslint-plugin: ^5.30.0
@typescript-eslint/parser: ^5.30.0"]
end
subgraph "代码质量工具"
ESLint["eslint: ^8.50.0"]
Prettier["prettier: ^2.7.1"]
ESLintConfig["eslint-config-prettier: ^6.12.0
eslint-config-standard: ^16.0.3"]
end
subgraph "框架专用 Lint"
ESLintVue["eslint-plugin-vue: ^8.7.1
vue-eslint-parser: ^9.3.1"]
ESLintReact["eslint-plugin-react: ^7.21.5"]
end
subgraph "其他插件"
ESLintImport["eslint-plugin-import: ^2.28.1"]
ESLintNode["eslint-plugin-node: ^11.1.0"]
ESLintPromise["eslint-plugin-promise: ^5.1.0"]
YAMLParser["yaml-eslint-parser: ^1.0.1"]
end
TS --> TSTypes
ESLint --> ESLintConfig
ESLint --> Prettier
ESLint --> ESLintVue
ESLint --> ESLintReact
ESLint --> ESLintImport
ESLint --> ESLintNode
ESLint --> ESLintPromise这些依赖支持:
- 使用 4.7.4 版本进行 TypeScript 编译
- 使用 Vue 与 React 插件进行 多框架 Lint
- 使用 Prettier 进行 代码格式化
- Standard JavaScript 代码风格约束
- 用于配置文件的 YAML 解析
版本管理
所有包都保持同步的版本号,目前为 3.0.3。这种同步版本策略:
- 简化依赖管理:用户能够确认各包之间的兼容版本
- 支持原子化发布:所有平台一起发布
- 保持 API 一致性:版本号反映共享核心的变更
graph LR
Release["发布 3.0.3"]
subgraph "所有包均为 v3.0.3"
Vue3["@relation-graph/vue"]
Vue2["@relation-graph/vue2"]
React["@relation-graph/react"]
Svelte["@relation-graph/svelte"]
WebComp["@relation-graph/web-components"]
end
Release --> Vue3
Release --> Vue2
Release --> React
Release --> Svelte
Release --> WebComp通过 npm 分发
每个平台包都会在 npm 上以 @relation-graph scope 独立发布。这些包没有运行时依赖,使它们可以作为轻量级组件加入任何项目。
零运行时依赖
所有平台包都将 dependencies 设为空:
"dependencies": {}
这意味着:
- 打包产物包含所有必要的核心逻辑
- 运行时不需要任何外部库
- 用户只需要框架专用的 peer dependencies(Vue、React 或 Svelte)
包入口点
每个包都为不同的模块系统定义了多个入口点:
graph TB
NPMRegistry["npm Registry
@relation-graph/[platform]"]
subgraph "包元数据"
Main["main: relation-graph.umd.js
传统打包器,Node.js"]
Module["module: relation-graph.mjs
支持 ESM 的现代打包器"]
Unpkg["unpkg: relation-graph.umd.js
CDN 分发"]
Types["types: types/packages/platforms/[platform]/src/index.d.ts
TypeScript 定义"]
end
subgraph "使用方工具"
Webpack["Webpack"]
Rollup["Rollup"]
Vite["Vite"]
CDN["unpkg.com"]
IDE["VS Code / WebStorm"]
end
NPMRegistry --> Main
NPMRegistry --> Module
NPMRegistry --> Unpkg
NPMRegistry --> Types
Main --> Webpack
Module --> Rollup
Module --> Vite
Unpkg --> CDN
Types --> IDE安装示例
用户根据所用框架安装对应的平台包:
Vue 3 项目:
npm install @relation-graph/vue
Vue 2 项目:
npm install @relation-graph/vue2
React 项目:
npm install @relation-graph/react
Svelte 项目:
npm install @relation-graph/svelte
与框架无关(Web Components):
npm install @relation-graph/web-components
构建流程
完整的构建流程遵循以下阶段:
flowchart TD
Start["开发者运行:
npm run build-all"]
BuildScript["build-all.sh
执行"]
subgraph "每个平台的构建步骤"
Clean["清理上一次构建
Remove dist/"]
TSCompile["TypeScript 编译
tsc --project tsconfig.json"]
Bundle["模块打包
生成 UMD + ESM"]
TypeGen["生成类型定义
Extract .d.ts files"]
CopyAssets["复制资源
SCSS, static files"]
end
subgraph "构建产物"
UMD["relation-graph.umd.js"]
ESM["relation-graph.mjs"]
Types["types/**/*.d.ts"]
Styles["CSS/SCSS files"]
end
subgraph "包准备"
UpdatePkg["更新 package.json
校验入口点"]
ValidatePkg["校验包
npm pack --dry-run"]
end
Ready["准备发布
npm publish"]
Start --> BuildScript
BuildScript --> Clean
Clean --> TSCompile
TSCompile --> Bundle
TSCompile --> TypeGen
Bundle --> CopyAssets
TypeGen --> CopyAssets
Bundle --> UMD
Bundle --> ESM
TypeGen --> Types
CopyAssets --> Styles
UMD --> UpdatePkg
ESM --> UpdatePkg
Types --> UpdatePkg
Styles --> UpdatePkg
UpdatePkg --> ValidatePkg
ValidatePkg --> Ready仓库元数据
所有包共享通用的仓库与文档元数据:
| 字段 | 值 | 用途 |
|---|---|---|
repository.type |
git |
版本控制系统 |
repository.url |
git+https://github.com/seeksdream/relation-graph.git |
源代码位置 |
homepage |
http://relation-graph.com |
文档与演示 |
bugs.url |
https://github.com/seeksdream/relation-graph/issues |
问题追踪 |
directories.doc |
doc |
文档目录 |
directories.example |
examples |
示例应用 |
目录结构
该 monorepo 可能遵循如下结构:
relation-graph/
├── package.json # 根包
├── build-all.sh # 构建编排脚本
├── tsconfig.json # 共享 TypeScript 配置
├── packages/
│ └── core/ # 共享核心实现
│ ├── src/
│ └── types/
├── platforms/
│ ├── vue3/
│ │ ├── package.json # @relation-graph/vue
│ │ ├── src/ # Vue 3 组件
│ │ ├── relation-graph.umd.js # 构建输出
│ │ ├── relation-graph.mjs # 构建输出
│ │ └── types/ # 生成的类型定义
│ ├── vue2/
│ │ ├── package.json # @relation-graph/vue2
│ │ └── ...
│ ├── react/
│ │ ├── package.json # @relation-graph/react
│ │ └── ...
│ ├── svelte/
│ │ ├── package.json # @relation-graph/svelte
│ │ └── ...
│ └── web-components/
│ ├── package.json # @relation-graph/web-components
│ └── ...
├── doc/ # 文档
└── examples/ # 示例应用
该结构使得:
- 共享核心逻辑:所有平台引用相同的核心实现
- 平台隔离:每个平台都有自己的构建输出
- 独立发布:如有需要,包可以分别发布
- 集中式工具链:构建工具与配置共享