@mxyu/dep-graph
v0.1.0
Published
组件依赖可视化 SDK:静态分析(Vue/React)+ AntV G6 可交互依赖图谱 + CLI/编程 API
Maintainers
Readme
@mxyu/dep-graph
组件依赖可视化 SDK:对 Vue 3 / React 项目做静态依赖分析,产出标准化依赖图 JSON(团队 v3.0 platform-deps.json 契约),并提供 AntV G6 可交互依赖图谱组件。
三种接入形态:
- CLI:
mxyu-depgraph analyze ./src --out platform-deps.json(供 CI 存档)。 - 编程 API:
import { analyzeProject } from '@mxyu/dep-graph'。 - Vue 组件:
<DependencyGraph :data="graph" />+ headlessuseDependencyGraph(从@mxyu/dep-graph/vue子入口导入)。
架构:分析引擎在 Node 运行(用
node:fs扫目录),从主入口@mxyu/dep-graph导入;可视化组件在浏览器渲染 JSON,从子入口@mxyu/dep-graph/vue导入(不含node:fs,可安全打进浏览器/Vite 构建)。推荐流程是「Node 分析 → 落盘 JSON → 浏览器渲染」,分析与展示解耦。
安装
monorepo 内(workspace):
// 消费方 package.json
{
"dependencies": {
"@mxyu/dep-graph": "workspace:*",
"vue": "^3.5.0" // 仅渲染组件时需要(peer,可选)
}
}外部安装:
pnpm add @mxyu/dep-graph
# 渲染组件还需 vue(peer,可选):pnpm add vue@antv/g6、@babel/parser、@vue/compiler-sfc 已作为依赖随包安装,构建时被外部化(不打进 SDK 产物),消费方透传即可。
CLI
mxyu-depgraph analyze <目录> [选项]| 选项 | 说明 | 默认 |
|---|---|---|
| --id <id> | 项目标识(写入 JSON) | project |
| --name <名> | 项目展示名 | 同 id |
| --framework vue\|react\|auto | 框架,auto 自动推断 | auto |
| --out <文件> | 输出 JSON 路径;已存在则按多项目合并 | platform-deps.json |
| --exclude <目录> | 排除目录(可重复传入) | — |
示例(分析本仓库自身的 uploader 包):
mxyu-depgraph analyze packages/uploader/src --id uploader --name "@mxyu/uploader" --framework vue --out platform-deps.json
# ✅ 分析完成:27 组件 / 67 依赖 / 循环 1,已写入 platform-deps.json多次对不同目录执行同一 --out,会按 v3.0 §5.4 合并为多项目,并计算 shared_registry(跨项目共享组件)。
编程 API
分析引擎(Node)
import { analyzeProject, analyzeToFile } from '@mxyu/dep-graph';
import type { ProjectGraph, PlatformDeps } from '@mxyu/dep-graph';
// 返回单项目图(内存对象)
const graph: ProjectGraph = analyzeProject('packages/uploader/src', {
id: 'uploader',
name: '@mxyu/uploader',
framework: 'vue', // 'vue' | 'react' | 'auto'
exclude: ['__test__'],
});
// 分析并写盘(已存在则合并为多项目 platform-deps.json)
const platform: PlatformDeps = analyzeToFile('packages/uploader/src', 'platform-deps.json', {
id: 'uploader',
});分析增强 / 报告(按需)
import {
buildProjectGraph, // 底层:scan → extract → parse → resolve → 建图
findCycles, // Tarjan SCC 找循环依赖
computeHealthScore, // 健康度 0-100
findHighRisk, // 高风险 Top-N(按入度)
findIsolated, // 孤立组件(入出度均 0)
collectExternalPackages, // 外部包汇总
impactOf, // 影响范围:选定组件 → 上游(反向 BFS)
subgraphOf, // 导出子图 JSON(F-07)
diffGraphs, // 两快照增删 diff(F-13)
impactReportMarkdown, // 影响范围 Markdown 报告(F-12)
toPlatformDeps, // ProjectGraph → PlatformDeps
mergeIntoPlatform, // 合并新项目到既有 PlatformDeps
} from '@mxyu/dep-graph';别名解析
支持相对路径、tsconfig.json 的 paths 别名、index 文件、省略扩展名、动态 import()。可显式读取别名:
import { readTsconfigAliases, aliasesFromTsconfigPaths } from '@mxyu/dep-graph';
const aliases = readTsconfigAliases('tsconfig.json'); // 例如 { '@/*': 'src/*' }Vue 可视化组件
在浏览器/Vite 环境使用,渲染已生成的
ProjectGraphJSON。
<script setup lang="ts">
import { DependencyGraph } from '@mxyu/dep-graph/vue';
import type { DepNode, ProjectGraph } from '@mxyu/dep-graph/vue';
import graphJson from './uploader-deps.json'; // CLI 预生成
const graph = graphJson.projects[0] as ProjectGraph;
function onNodeClick(node: DepNode) {
console.log('点击节点', node.id, node.path);
}
</script>
<template>
<DependencyGraph :data="graph" layout="force" :height="600" @node-click="onNodeClick" />
</template>Props
| Prop | 类型 | 默认 | 说明 |
|---|---|---|---|
| data | ProjectGraph | — | v3.0 单项目依赖图(必填) |
| layout | 'force' \| 'dagre' \| 'radial' | 'force' | 力导 / 层次 / 辐射布局 |
| theme | 'dark' \| 'light' | 'dark' | 主题;深色默认,浅色切换(标签文本色随主题,WCAG AA) |
| maxNodes | number | 0 | 渲染节点上限;超过则按重要度(度数)降级限流,0 不限制 |
| height | number | 600 | 画布高度(px) |
Events
| 事件 | 载荷 | 说明 |
|---|---|---|
| node-click | DepNode | 点击节点,携带原始节点,供右侧详情面板使用 |
暴露方法(ref 调用)
| 方法 | 说明 |
|---|---|
| getInstance() | 获取底层 G6 Graph 实例 |
| highlightNeighbors(id) | 高亮某节点上下游,其余置灰 |
| clearHighlight() | 清除高亮 |
| focusNode(id, depth?) | 专注模式:仅高亮 N 级邻域(默认 2) |
| searchNode(id) | 搜索定位并居中 |
| getDegradeInfo() | 返回 { degraded, hiddenCount }(大图限流时被折叠的节点数) |
headless 组合式
import { useDependencyGraph } from '@mxyu/dep-graph/vue';
const handle = useDependencyGraph(containerEl, graph, {
layout: 'force',
onNodeClick: node => { /* ... */ },
});
handle.setLayout('dagre');
handle.focusNode('FileItem', 2);
handle.destroy();视觉编码 / 交互数据层(无 G6,可单测)
toRenderModel、nodeVisual / edgeVisual(颜色/大小/边粗细)、neighbors、focusSubgraph、tracePaths(路径追踪 DFS)、filterNodeIds(过滤)、degradeGraph(大图按重要度限流降级)。
图数据格式(v3.0 platform-deps.json)
字段统一 snake_case,与团队 v3.0 序列化结构一致。
{
"schema_version": "3.0",
"generated_at": "ISO 时间",
"projects": [
{
"id": "uploader",
"name": "@mxyu/uploader",
"framework": "vue",
"root_dir": "packages/uploader/src",
"collected_at": "ISO 时间",
"tool": "@mxyu/dep-graph",
"meta": {
"total_nodes": 27,
"total_edges": 67,
"circular_count": 1,
"isolated_count": 0,
"health_score": 90
},
"nodes": [
{
"id": "FileItem",
"path": "components/FileItem.vue",
"framework": "vue",
"node_type": "SFC", // SFC|FC|Class|HOC|Hook|Context|Lazy|Unknown
"group": "unknown", // atoms|molecules|organisms|layout|pages|hooks|context|unknown
"file_type": "vue", // tsx|jsx|vue|ts|js
"in_degree": 2,
"out_degree": 5,
"lines": 120,
"size_bytes": 3200,
"external_deps": ["vue"],
"last_modified": "ISO 时间",
"is_shared": false
}
],
"edges": [
{ "source": "FileItem", "target": "FilePreview", "edge_type": "static" } // static|dynamic|hoc|context
],
"cycles": [["uploadExecutor", "useUploader"]]
}
],
"shared_registry": []
}完整 TypeScript 类型:PlatformDeps / ProjectGraph / ProjectMeta / DepNode / DepEdge / SharedRegistryEntry(均从入口导出)。
FAQ
Q:分析引擎能在浏览器跑吗?
不能。分析用 node:fs 扫描目录,只在 Node/CLI 运行。浏览器侧只负责渲染已生成的 JSON。推荐:CI/脚本里跑分析落盘 JSON,前端 import 该 JSON 后用 <DependencyGraph> 渲染。
Q:为何 group 是 unknown?
分层按目录关键词推断(atoms/molecules/organisms/layout/pages 等,v3.0 §4.6)。扁平目录结构会落到 unknown,属预期,不影响图谱。
Q:循环依赖怎么算的?
Tarjan 强连通分量(SCC),cycles 给出每个环的节点序列,meta.circular_count 为环数量。
Q:G6 会被打进我的包吗?
不会。@antv/g6、@babel/*、@vue/compiler-sfc 在 SDK 构建时外部化,由消费方依赖透传。
已知限制 / 路线
- 入口拆分(已落地):可视化组件与 Node 分析引擎已拆为两个入口——主入口
@mxyu/dep-graph(分析引擎,含node:fs)与浏览器子入口@mxyu/dep-graph/vue(组件 + G6,无node:fs)。前端从/vue引入即可,分析产物在 Node 侧预生成为 JSON。 - React 富类型:
node_type的Class/HOC/Hook/Context/Lazy细分为后续增强项,v1 以SFC/FC为主。 - 大图性能:v1 面向中型项目(≤2000 组件)。已提供按重要度限流降级——
maxNodesprop /degradeGraph():节点超阈值时保留度数最高的 Top-N 及其内部边、其余折叠(getDegradeInfo()报告折叠数)。更强的聚合/虚拟渲染为后续加固项。 - 构建产物:ESM + CJS +
.d.ts(主入口与./vue子入口各一套)。不产出 IIFE:主入口含node:fs无法构建为浏览器 IIFE;./vue子入口的 IIFE 需 G6/Vue 全局且属小众消费方式,按 DoD「按需」评估暂不产出(消费方走 ESM/CJS 或打包器)。
质量门禁
pnpm exec vitest run --project dep-graph # 单测
pnpm exec tsc -p packages/dep-graph/tsconfig.json --noEmit # 类型
pnpm exec eslint packages/dep-graph # 格式(权威)
pnpm -F @mxyu/dep-graph build # 产物 ESM/CJS + d.ts许可证:MIT
