用途
Conformetry 生成器把模板(一个普通文件夹中的普通文件)渲染为磁盘上的实例。同一个模板随后成为衡量实例的标准,因此生成不是便利手段:手写一个模板已经描述的形状,代码从诞生起就不合规。在手动写文件之前,应先检查是否存在生成器。
主要能力
- 通过模板渲染生成模块、组件、服务、应用或包等实例。
- 模板同时作为合规标准,生成实例按构造即合规。
- 提供 Nx 插件与命令行宿主两种入口。
- 支持
--dry-run(Nx 路径)预览将写入的内容。 - 生成后可用 conformetry-validate 检查合规性。
使用方式
查找生成器
不要猜测生成器名称,应读取注册表:
conformetry templates
在 Nx 工作区中,生成的插件回答同一问题:
nx list conformetry
两者都读取实时配置,因此对当前工作区是正确的。输出会随生成器增减而变化,不值得缓存到笔记中。
生成会无条件覆盖
写入路径中没有任何存在性检查、跳过已存在、合并或冲突检测。模板中的每个文件都会被渲染并覆盖现有内容。
绝不要把生成器指向已经存放你想要保留的工作的路径。要修改现有实例,就编辑它。只有在打算丢弃现有内容,或实例缺少模板要求的文件且你已阅读将被替换的内容时,才重新生成。
Nx 路径通过 Tree 写入,因此 --dry-run 是诚实的,会准确显示将写入什么:
nx g conformetry:<generator> --name=<name> --project=<project> --dry-run
不确定输出会去哪里时,先执行这一步。
两个入口对输入的要求不一致
这是生成中最令人困惑的一点,且不是缺陷:同一个生成器因调用方式不同而行为不同。
| Nx 插件 | 命令行宿主 | |
|---|---|---|
| 调用 | nx g conformetry:<name> |
conformetry generate --template <name> |
| 输入 | 每个声明的输入都必需 | 没有任何输入是必需的 |
| 缺少输入 | 拒绝或提示 | 当模板插值该输入时拒绝 |
| 默认目标 | 从工作区解析 | generated/<generator-name> |
剩余的不对称在于缺少值何时被捕获。Nx 路径预先要求每个声明的输入,因此在渲染开始前就拒绝。命令行宿主不要求任何输入,在模板请求该值时捕获遗漏——MissingSubstitutionError,并指出占位符和模板文件。
因此,模板从不插值的输入在命令行宿主上可以省略,在 Nx 路径上则不行。模板确实插值的任何内容在两条路径上都是必需的。
在任一路径上都显式传入每个输入。表示“可选”的模板用 section 表达——{{#owner}}…{{/owner}} 在 owner 缺失时不渲染任何内容——而不是依赖裸 {{owner}}。
生成器在两条路径上都以完整名称寻址——没有短的替代名称。名称错误时,两个宿主都会列出真实名称。
标志是 --template,不是 --generator。它与配置(templatePath)、templates 命令和合规报告已使用的词一致。--generator 已被移除而非保留为别名,传入它会按名称被拒绝——该命令接受未知标志以便模板输入可作为标志传入,因此没有这种拒绝,过时脚本的 --generator 会被静默丢弃并看似正常工作。
--template 在命令行上也是可选的。在终端省略它会提供对所有已配置模板的自动补全,每个都带描述;agent shell 不是终端,因此始终传入它——在那里省略,运行会被拒绝并列出可用名称,而不是等待提示。
输出落在哪里
在 Nx 路径上,目标按以下顺序解析,首个匹配胜出:
- 显式的
--directory。 - 没有 project 输入——视为新项目,按其 type 输入放置在同类型项目旁。
- 有 module 输入——放置在该现有模块中。命名不存在的模块是错误,不是创建它的邀请。
- 生成器自己的作用域目录,来自其实例组中第一个带标签的模式。
- 已持有该生成器最多实例的目录。
- 项目根。
第 4 和第 5 步是生成器通常完全不需要目标的原因:它知道自己的实例住在哪里。当你故意把东西放在该约定之外时,才用 --directory。
在命令行宿主上只有 --directory 适用,其缺失意味着 generated/<generator-name>——一个临时位置,不是你的源码树。在那里要写入工作区时,始终传入 --directory。
无人值守运行
命令行宿主在 stdin 是终端时提示,且没有标志可关闭——附加终端就是全部条件,因此 agent shell、hook 或 CI 作业永远不会被提示。
生成器声明的每个输入在两个入口上都是必需的:生成器替换其每个占位符,而 mustache 将缺失的占位符渲染为空字符串而非失败,因此可选输入会悄悄在生成文件中留下空洞。没有终端时,未传入的输入因此是硬错误,并指出要传入的标志——绝不是静默默认值,也绝不在无人能回答的地方绘制菜单。传入模板声明的每个输入,或在能被询问的地方运行。
生成之后
两个步骤,都很廉价,都能捕获一整类错误:
- 检查刚生成内容的合规性。生成的实例按构造即合规,因此差异意味着目标错误、输入为空,或你覆盖了某些东西。参见 conformetry-validate 技能。
- 在生成的文件内部实现。不要在它们旁边构建并行结构。模板的 section 注释和声明就是契约;向其中添加总是允许的,移除它们才是破坏。
当生成器尚不存在时
添加一个是配置变更,不是代码变更——参见 conformetry-configure 技能。之后立即有两件事会咬人:生成的 Nx 插件必须用 nx sync 重新生成,且每个 conformetry 命令在它过时时都会拒绝运行,而不是基于过时定义工作。
看它而不是读它
conformetry-examples 是十一个自包含示例,每个都有自己的配置、模板、实例和命令。在脚手架化不熟悉的东西之前,有两个值得运行:
- hello-template——存在的最小生成器,用两条命令生成然后验证,因此循环端到端可见。
- case-variants——路径和内容中的每个派生大小写变体,以及显式输入如何覆盖其中一个。
每个运行约一秒,其指南引用它产生的输出,该包自己的测试套件对此进行断言。参见其 AGENTS.md 了解哪个示例回答哪个问题。
适用场景
- 向工作区添加模块、组件、服务、应用或包。
- 需要按模板标准生成合规实例。
- 在 Nx 工作区或命令行环境中脚手架化代码。
限制
- 生成无条件覆盖,无存在性检查、跳过、合并或冲突检测。
- 不能指向已有工作成果的路径。
- 两个入口对输入要求不一致,需显式传入每个输入。
- 命令行宿主默认输出到临时位置,需显式传
--directory。 - 无终端时未传入的输入是硬错误。
- 生成器名称必须完整,无短别名。
- 标志是
--template,--generator已被移除。 - 添加生成器后需
nx sync重新生成 Nx 插件。 - 官方文本暂未提供。