news 2026/9/29 7:16:55

dependency-cruiser 配置 Schema 体系:从单一事实来源到运行时校验的生成工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
dependency-cruiser 配置 Schema 体系:从单一事实来源到运行时校验的生成工作流
  • 开发工具
  • 静态分析
  • 代码质量

【免费下载链接】dependency-cruiser

Validate and visualize dependencies. Your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

项目地址:https://gitcode.com/gh_mirrors/de/dependency-cruiser
点击查看免费下载

本篇技术指南聚焦 dependency-cruiser 仓库中的src/schema/目录,讲解其 JSON Schema(配置 Schema 与巡航结果 Schema)如何由tools/schema/下的源定义生成、如何通过 Ajv 编译成独立校验器,以及这些校验器如何在 CLI 运行时与格式化阶段被真实调用。读完本文,你将掌握该项目的 Schema 生成脚本、Makefile 自动化规则、产物形态与运行时消费链路,并能独立完成"修改 Schema 定义 → 重新生成 → 验证生效"的完整操作。

一、src/schema/README.md说了什么:一条"源定义 → 生成产物"的工作流

仓库根目录下的 src/schema/README.md 用极简的篇幅定义了本目录的维护纪律,是理解整个 Schema 体系的入口:

  • src/schema/下的 JSON Schema 文件由tools/generate-schemas.utl.mjs脚本生成;
  • 其中的校验器文件由tools/generate-schema-validator.utl.mjs脚本生成;
  • 如果需要对 Schema 做修改,不要直接编辑src/schema/下的生成产物,而是修改 tools/schema/ 中的源定义;
  • 修改之后重新运行生成脚本,既可以执行make,也可以分别运行node tools/generate-schemas.utl.mjs与node tools/generate-schema-validator.utl.mjs。

这条规则意味着src/schema/是一个"生成目录",它的内容全部是机器产物;而tools/schema/才是人工维护的"单一事实来源"(Single Source of Truth)。

二、单一事实来源:tools/schema/下的 Schema 源定义

tools/schema/目录以 ES Module(.mjs)形式组织 Schema 定义,共约三十个模块,按职责可分为几组:

  • 顶层配置组合:configuration.schema.mjs、cruise-result.schema.mjs、baseline-violations.schema.mjs;
  • 规则集定义:rule-set.mjs(forbidden/allowed/allowedSeverity/required)、restrictions.mjs(from/to等约束类型)、severity-type.mjs;
  • 巡航选项定义:options.mjs、cache-options.mjs、compound-*-type.mjs(doNotFollow、exclude、includeOnly、focus、highlight、reaches等复合类型)、module-systems-type.mjs、output-type.mjs、reporter-options.mjs、experimental-stats-type.mjs;
  • 巡航结果结构:modules.mjs、dependencies.mjs、dependency-type.mjs、mini-dependency-type.mjs、folders.mjs、summary.mjs、violations.mjs、violation-type.mjs、rule-summary.mjs、revision-data.mjs、options-used.mjs等。

以 tools/schema/configuration.schema.mjs 为例,顶层配置 Schema 通过模块组合完成:properties直接展开ruleSet.properties,再追加options与extends两个引用;definitions则合并ruleSet.definitions、options.definitions与自定义的ExtendsType(支持单个字符串或字符串数组,表示该配置所继承的基配置)。ruleSet.properties则由 tools/schema/rule-set.mjs 提供:forbidden(禁止的依赖规则)、allowed(允许的依赖规则,违反时输出not-in-allowed警告)、allowedSeverity(not-in-allowed的严重级别,默认warn)与required(模块必须具备的依赖,例如每个 controller 必须直接依赖 base controller)。所有规则类型均设置additionalProperties: false,杜绝未知字段静默通过。

三、三种产物形态:.schema.json、.schema.mjs与.validate.mjs

生成脚本会产出三种文件,各自承担不同角色:

产物示例用途
可读 JSON Schemasrc/schema/configuration.schema.json面向人阅读、IDE 提示与外部工具(如编辑器基于$schema做自动补全)
紧凑 ESM Schemasrc/schema/configuration.schema.mjs(中间产物,Makefile 会在校验器生成后清理)供生成校验器时以 JS 模块形式被import
独立校验器src/schema/configuration.validate.mjs、src/schema/cruise-result.validate.mjs运行时被 CLI 直接调用,校验配置与巡航结果

其中 src/schema/configuration.schema.json 声明了$id: https://dependency-cruiser.js.org/schema/configuration.schema.json,顶层properties仅允许$schema、forbidden、allowed、allowedSeverity、required、options、extends七个键,并整体设置additionalProperties: false。

四、生成脚本剖析:tools/generate-schemas.utl.mjs

src/schema/README.md 指定的第一个生成脚本是 tools/generate-schemas.utl.mjs,其关键行为如下:

1. 按目标文件扩展名分派输出格式

emitConsolidatedSchema(pOutputFileName)依据扩展名决定产物形态:

  • 目标是.json时:用 prettier 的jsonparser 对JSON.stringify(schema.default)做格式化后写入;
  • 目标是.mjs时:先通过stripAttribute递归删除所有description字段(减小体积),拼装成/* generated - don't edit */ export default {...}形式的 ESM 模块,再用 prettier 的 babel parser 格式化、最后经@babel/core的transformSync(..., { minified: true })压缩后写入。

2. 通过正则推导输入模块名

getInputModuleName(pOutputFileName)从输出路径(如./src/schema/configuration.schema.json)反推输入源定义(./configuration.schema.mjs),即tools/schema/下同名.schema.mjs模块。

3. 强制 Node 权限模型

脚本开头检查process.permission,并要求在 Node 的 Permission Model(--permission)下运行,随后尝试drop对..与/的读写权限,缩小脚本自身的能力边界。用法为:

node tools/generate-schemas.utl.mjs ./src/schema/configuration.schema.json

五、校验器生成剖析:tools/generate-schema-validator.utl.mjs

src/schema/README.md 指定的第二个脚本是 tools/generate-schema-validator.utl.mjs。它基于 Ajv 的 standalone 代码生成能力:

  1. 用new Ajv({ code: { source: true, esm: true } })创建编译器实例(产出 ESM 形态的源码级校验代码);
  2. import输入的.schema.mjs并ajv.compile(schema.default);
  3. 调用standaloneCode(ajv, validate)把编译结果导出为不依赖 Ajv 运行时的独立模块,写入输出文件。

用法(脚本自带 Usage 示例):

node tools/generate-schema-validator.utl.mjs ./src/schema/configuration.schema.mjs ./src/schema/configuration.validate.mjs

生成出的 src/schema/configuration.validate.mjs 是压缩后的 ESM:开头即export const validate=de;export default de;,全部校验逻辑内联为普通函数(如对SeverityType的["error","warn","info","ignore"]枚举、对dependencyTypes的约四十个枚举值的逐项检查、对additionalProperties的键白名单检查等),可被任何 ESM 环境直接 import 使用。

六、Makefile 自动化:make build一键重建

Makefile 将上述两步脚本编排成 make 规则,README 中"重新运行生成脚本(either by runningmake...)"指的就是这套自动化:

  • build目标依赖三组文件:GENERATED_SOURCES(baseline-violations.schema.mjs/json、configuration.schema.json、cruise-result.schema.json、src/meta.cjs)、GENERATED_VALIDATORS(两个.validate.mjs);
  • 生产规则src/%.schema.mjs: tools/%.schema.mjs $(SCHEMA_SOURCES) tools/generate-schemas.utl.mjs与同款.json规则,把tools/schema/源定义连同全部SCHEMA_SOURCES一起作为依赖,用$(NODE) --allow-fs-read ./ --allow-fs-write ./src/schema/执行生成脚本(这里的--permission正是脚本内部检查所要求的);
  • 生产规则src/schema/%.validate.mjs: src/schema/%.schema.mjs tools/generate-schema-validator.utl.mjs先生成未压缩校验器,随后npx esbuild --tree-shaking=true --minify二次压缩,最后$(RM) $<删除作为中间产物的.schema.mjs(所以在最终仓库里只见.schema.json与.validate.mjs);
  • clean目标删除全部生成产物,help目标说明build与clean的用途。

七、运行时消费链路:校验器在 CLI 与格式化阶段被真实调用

生成的校验器并非摆设,而是贯穿 dependency-cruiser 主流程的硬性检查:

  • 配置校验:src/main/rule-set/assert-validity.mjs 导入#schema/configuration.validate.mjs,在assertSchemaCompliance中调用validateConfigurationSchema(pConfiguration),校验失败即抛出The supplied configuration is not valid: ...并附上错误详情——这意味着任何非法配置在巡航开始前就会被拒绝;
  • 结果校验:src/main/format.mjs 导入#schema/cruise-result.validate.mjs,在格式化输出前用validateCruiseResultSchema(pResult)校验巡航结果,失败抛出The supplied dependency-cruiser result is not valid: ...;
  • 错误格式化:src/schema/utl.mjs 提供validateErrorsToString(pErrors),把 Ajv 错误数组(instancePath+message)拼接成可读字符串,供上述两处抛错使用。

由此可以确认一条完整链路:开发者修改tools/schema/源定义 →make build或两个node脚本重新生成src/schema/产物 → CLI 运行时经assert-validity.mjs用新校验器拦截非法配置。

八、实践指引:修改 Schema 的标准操作流程

结合 src/schema/README.md 的约定与上述源码证据,为 dependency-cruiser 扩展配置项的推荐流程是:

  1. 改源定义:在 tools/schema/ 中编辑对应的.schema.mjs(新增配置项时通常涉及options.mjs及其引用类型模块);
  2. 重新生成:在仓库根目录执行make build;若只想重建单个文件,可按 README 给出的命令分别执行node tools/generate-schemas.utl.mjs与node tools/generate-schema-validator.utl.mjs(注意脚本需要 Node 的--permission模式,直接运行请参照 Makefile 中的$(NODE)定义补齐权限参数);
  3. 验证生效:编写带新字段的.dependency-cruiser.cjs配置运行depcruise,确认不再触发assertSchemaCompliance的抛错,且旧配置仍可通过校验(回归);
  4. 保持纪律:绝不手工编辑src/schema/下的生成产物——它们带有生成标记或被压缩,手工改动会在下次make build时被覆盖。

对使用 dependency-cruiser 的普通用户而言,同样能从这套体系受益:在配置文件中声明"$schema": "https://dependency-cruiser.js.org/schema/configuration.schema.json",编辑器即可基于仓库公开的 Schema 提供配置键补全与非法字段提示,把大部分配置错误消灭在编写阶段,而不是等到 CLI 运行时才收到The supplied configuration is not valid的报错。

  • 开发工具
  • 静态分析
  • 代码质量

【免费下载链接】dependency-cruiser

Validate and visualize dependencies. Your rules. JavaScript, TypeScript, CoffeeScript. ES6, CommonJS, AMD.

项目地址:https://gitcode.com/gh_mirrors/de/dependency-cruiser
点击查看免费下载

相关推荐

上一篇:3D打印螺纹总卡死?CustomThreads完整指南让Fusion 360螺纹一次旋合
下一篇:radix-vue HoverCardTrigger 深度解析:悬浮卡片触发器的定位锚点、事件语义与 Props 详解

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 7:15:58

ChanlunX实战:缠论分型、笔、中枢与买卖点代码化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 7:15:26

读懂Vivado时序报告:FPGA时序收敛的核心能力

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 7:15:16

Linux内核mynext字段的逻辑地址与线性地址解析

1. 这不是教科书里的概念题&#xff0c;而是内核调度器里真实跳动的脉搏“1/0 号进程 mynext 变量的逻辑地址与线性地址”——看到这个标题&#xff0c;别急着翻《操作系统原理》附录或去查页表结构图。我第一次在 Linux 2.6.32 内核源码里盯住init_task和idle_task的mynext字段…

作者头像 李华
网站建设 2026/9/29 7:15:08

UM2 3D打印机DIY电路篇:24V供电、步进驱动与电流校准全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 7:14:18

庭院落叶清运服务的季节规律与操作要点

一、落叶清运服务的典型时间窗口 每年秋季进入深秋后&#xff0c;多数落叶乔木开始大量脱叶&#xff0c;这一阶段是清运服务的主要集中期。根据气候观测数据&#xff0c;长江中下游地区在10月下旬至12月中旬之间&#xff0c;叶片脱落速度明显加快&#xff0c;此时园林养护单位…

作者头像 李华