JavaScript is required

构建系统与分发

本文档描述了 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 脚本负责协调五个平台包的构建流程。该脚本可能会:

  1. 将 TypeScript 源文件编译为 JavaScript
  2. 将代码打包为 UMD 与 ESM 格式
  3. 生成 TypeScript 声明文件
  4. 复制资源与样式
  5. 为每个平台包准备 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 --> TypeScriptIDE

UMD 格式(Universal Module Definition)

relation-graph.umd.js 文件提供一个可在多种环境下工作的通用模块:

  • 浏览器全局变量:可通过 <script> 标签加载,暴露一个全局变量
  • AMD 模块:兼容 RequireJS
  • CommonJS:可用于 Node.js 的 require()
  • CDN 分发:由 unpkg 字段引用,适用于 unpkg.com 等服务

mainunpkg 字段都指向该产物,使其成为传统打包器与 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 version
  • vue relationship graph
  • vue knowledge graph
  • vue 关系图谱(中文:relationship graph)
  • vue 知识图谱(中文:knowledge graph)

React 包关键词:

  • relation-graph react version
  • react relationship graph
  • react graph editor
  • react 图谱编辑器(中文: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。这种同步版本策略:

  1. 简化依赖管理:用户能够确认各包之间的兼容版本
  2. 支持原子化发布:所有平台一起发布
  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/                            # 示例应用

该结构使得:

  • 共享核心逻辑:所有平台引用相同的核心实现
  • 平台隔离:每个平台都有自己的构建输出
  • 独立发布:如有需要,包可以分别发布
  • 集中式工具链:构建工具与配置共享