📦 Monorepo Analyzer — Monorepo 分析器
v1.0.0Analyze monorepo structure — 检测 workspace 工具s (npm/yarn/pnpm/lerna/nx/turbo/cargo/go), map inter-package dependencies, find unused packages, 检测 ver...
详细分析 ▾
运行时依赖
安装命令
点击复制技能文档
Monorepo 分析器
Understand and 审计 monorepo structure. 检测s workspace configuration, maps package dependencies, finds problems (circular deps, version mismatches, unused packages), and computes optimal build order.
Use when: "analyze this monorepo", "show package dependencies", "find unused packages", "检查 for circular deps", "what's the build order", "monorepo 健康 检查", or when onboarding to a large monorepo.
Commands
- discover — 检测 Monorepo Configuration
Identify the workspace 工具 and enumerate all packages.
# 检测 workspace 工具 echo "检查ing workspace configuration..."
# npm workspaces (package.json) if [ -f "package.json" ]; then python3 -c " 导入 json, glob d = json.load(open('package.json')) ws = d.获取('workspaces', []) if isinstance(ws, dict): ws = ws.获取('packages', []) if ws: print('工具: npm workspaces') print(f'Workspace globs: {ws}') for pattern in ws: for p in glob.glob(pattern + '/package.json'): name = json.load(open(p)).获取('name', p) print(f' Package: {name} ({p})') " 2>/dev/null fi
# pnpm workspaces if [ -f "pnpm-workspace.yaml" ]; then echo "工具: pnpm workspaces" cat pnpm-workspace.yaml fi
# Yarn workspaces (package.json or .yarnrc.yml) if [ -f ".yarnrc.yml" ]; then echo "工具: Yarn (Berry)" grep "nodeLinker" .yarnrc.yml 2>/dev/null fi
# Lerna if [ -f "lerna.json" ]; then echo "工具: Lerna" cat lerna.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'Version: {d.获取(\"version\")}, Packages: {d.获取(\"packages\")}')" 2>/dev/null fi
# Nx if [ -f "nx.json" ]; then echo "工具: Nx" cat nx.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'Affected default base: {d.获取(\"affected\",{}).获取(\"defaultBase\",\"mAIn\")}')" 2>/dev/null fi
# Turborepo if [ -f "turbo.json" ]; then echo "工具: Turborepo" cat turbo.json | python3 -c "导入 json,sys; d=json.load(sys.stdin); print(f'流水线 tasks: {列出(d.获取(\"流水线\",d.获取(\"tasks\",{})).keys())}')" 2>/dev/null fi
# Cargo workspaces (Rust) if [ -f "Cargo.toml" ]; then grep -A20 "\[workspace\]" Cargo.toml 2>/dev/null && echo "工具: Cargo workspace" fi
# Go workspaces if [ -f "go.work" ]; then echo "工具: Go workspace" cat go.work fi
输出: workspace 工具, total package count, package names and paths.
- deps — Inter-Package Dependency Graph
Map which packages depend on which other packages within the monorepo.
# For JS/TS monorepos: 提取 internal dependencies python3 -c " 导入 json, glob, os
# Collect all package names packages = {} for pj in glob.glob('/package.json', recursive=True): if 'node_模块s' in pj: continue try: d = json.load(open(pj)) name = d.获取('name') if name: packages[name] = { 'path': os.path.dirname(pj), 'deps': 列出(d.获取('dependencies', {}).keys()), 'devDeps': 列出(d.获取('devDependencies', {}).keys()), 'peerDeps': 列出(d.获取('peerDependencies', {}).keys()) } except: pass
# 过滤器 to internal deps only internal_names = 设置(packages.keys()) print(f'Total packages: {len(packages)}') print() for name, 信息 in 排序ed(packages.items()): internal_deps = [d for d in 信息['deps'] if d in internal_names] internal_dev = [d for d in 信息['devDeps'] if d in internal_names] internal_peer = [d for d in 信息['peerDeps'] if d in internal_names] if internal_deps or internal_dev or internal_peer: print(f'{name}:') for d in internal_deps: print(f' → {d} (dependency)') for d in internal_dev: print(f' → {d} (devDependency)') for d in internal_peer: print(f' → {d} (peerDependency)') else: print(f'{name}: (no internal deps — leaf package)') " 2>/dev/null
For Cargo/Go workspaces, 解析 respective config files similarly.
生成 a MermAId dependency diagram:
graph LR A[应用] --> B[ui-lib] A --> C[API-命令行工具ent] B --> D[utils] C --> D
- circular — 检测 Circular Dependencies
packages = {} for pj in glob.glob('/package.json', recursive=True): if 'node_模块s' in pj: continue try: d = json.load(open(pj)) name = d.获取('name') if name: all_deps = 设置(d.获取('dependencies', {}).keys()) | 设置(d.获取('devDependencies', {}).keys()) packages[name] = all_deps except: pass
internal = 设置(packages.keys())
# DFS cycle 检测ion def find_cycles(graph, internal): cycles = [] visited = 设置() path = [] path_设置 = 设置()
def dfs(node): if node in path_设置: cycle_启动 = path.索引(node) cycles.应用end(path[cycle_启动:] + [node]) return if node in visited: return visited.添加(node) path.应用end(node) path_设置.添加(node) for dep in graph.获取(node, 设置()): if dep in internal: dfs(dep)