Dependency-Cruiser 规则配置详解:从入门到精通
前言
在现代前端项目中,模块依赖关系管理是保证代码质量的重要环节。Dependency-Cruiser 作为一款强大的依赖关系分析工具,通过灵活的规则配置可以帮助开发者建立健康的项目依赖结构。本文将深入解析 Dependency-Cruiser 的规则配置体系,帮助开发者掌握依赖治理的核心能力。
规则配置文件基础结构
Dependency-Cruiser 的配置文件支持 JSON 和 JavaScript 两种格式,核心包含以下几个关键部分:
{
"forbidden": [], // 禁止的依赖规则
"allowed": [], // 允许的依赖白名单
"required": [], // 必须存在的依赖规则
"options": {} // 配置选项
}
1. 禁止规则(forbidden)
禁止规则用于定义项目中不允许出现的依赖关系。当检测到违规依赖时,Dependency-Cruiser 会根据配置的严重级别发出警告或错误。
典型应用场景:
- 禁止业务组件间相互引用
- 禁止直接引用底层实现而非接口
- 禁止使用已废弃的模块
示例配置:
{
"name": "no-cross-component-deps",
"comment": "禁止业务组件间相互引用",
"severity": "error",
"from": { "path": "^src/components/([^/]+)/.+" },
"to": {
"path": "^src/components/([^/]+)/.+",
"pathNot": "^src/components/$1/.+"
}
}
2. 允许规则(allowed)
允许规则定义了依赖的白名单,任何不在白名单中的依赖都会被标记。默认严重级别为"warn",可通过allowedSeverity
调整。
3. 必需规则(required)
必需规则确保特定模块必须包含某些依赖,支持直接依赖和间接依赖检查:
{
"required": [
{
"name": "controllers-must-extend-base",
"comment": "所有控制器必须继承基础控制器",
"module": {
"path": "-controller.js$",
"pathNot": "base-controller.js$"
},
"to": {
"path": "^src/base-controller.js$",
"reachable": true // 检查直接和间接依赖
}
}
]
}
规则继承机制
Dependency-Cruiser 支持通过extends
继承其他配置文件,实现规则复用:
{
"extends": [
"./base-rules.json",
"company-shared-rules/frontend"
]
}
继承规则合并策略:
allowed
规则会合并并去重- 同名
forbidden
和required
规则会深度合并 options
会采用Object.assign方式合并
规则条件详解
路径匹配(path/pathNot)
使用正则表达式匹配模块路径,支持分组捕获和引用:
{
"from": { "path": "^src/([^/]+)/.+" },
"to": {
"pathNot": "^src/$1/.+" // 使用from中的分组
}
}
孤儿模块检测(orphan)
检测没有依赖关系的孤立模块:
{
"name": "no-orphans",
"severity": "warn",
"from": { "orphan": true },
"to": {}
}
循环依赖检测(circular)
{
"name": "no-circular",
"severity": "error",
"from": {},
"to": { "circular": true }
}
许可证检查(license/licenseNot)
{
"name": "no-gpl",
"severity": "error",
"from": {},
"to": { "licenseNot": "GPL.*" }
}
高级规则配置
作用域控制(scope)
默认规则作用于模块级别,可通过scope
调整为文件夹级别:
{
"scope": "folder",
"from": { "path": "^src/main" },
"to": { "path": "^src/utils", "circular": true }
}
稳定性指标(moreUnstable)
基于Robert C. Martin的稳定性指标进行检查:
{
"name": "stable-deps-principle",
"comment": "稳定依赖原则",
"severity": "warn",
"scope": "folder",
"from": { "path": "^src/stable", "moreUnstable": false },
"to": { "path": "^src/volatile", "moreUnstable": true }
}
JavaScript 配置示例
对于复杂场景,可以使用JavaScript配置实现动态规则:
module.exports = {
forbidden: [
{
name: "no-cross-package-deps",
comment: "禁止跨产品线依赖",
severity: "error",
from: { path: `^src/products/(${getProducts().join("|")})/.+` },
to: { path: `^src/products/(?!$1)[^/]+/.+` }
}
]
};
function getProducts() {
// 动态获取产品线列表
return fs.readdirSync("src/products");
}
最佳实践建议
- 项目初始化时运行
depcruise --init
生成基础配置 - 从严格规则开始,逐步放宽限制
- 将公共规则提取为共享配置
- 在CI流程中加入依赖检查
- 结合可视化报告分析依赖关系
通过合理配置Dependency-Cruiser的规则体系,开发者可以建立清晰的模块边界,预防依赖混乱,提升项目的可维护性和架构质量。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考