在文件注释中编写模板,动态更新内容片段
在 Makeflow,我们使用 mono repo 来组织主项目,经常需要在不同的文件(如 README.md、gitlab-ci.yml、Dockerfile、tsconfig.json 等)中引用各种包、文件或目录。项目内容的增减都可能导致相关引用的修改,不熟悉相关内容的同事,常常会出现错误或者遗漏。而其中一些问题,可能很难及时发现。
为了解决这类问题,我们需要尽量将相关内容的更新自动化:使用模板和脚本自动更新,并加入 CI。在这个过程中,我们引入了一个新工具: makeflow/inplate ,它提供了一套简单的注释语法,可以将 handlebars 模板写在文件注释中,通过配置的变量来生成注释区域的内容。
以我们的主项目根目录 tsconfig.json 文件为例(当然实际上我们有几十个引用 ):
{ "references": [ // @inplate // {{#each nonRootTSProjectPaths}} // {"path": "{{this}}"}{{#unless @last}},{{/unless}} // {{/each}} // @plate {"path": "app/pack"}, {"path": "app/src/program"}, {"path": "app/src/service-worker"}, {"path": "website/pack"}, {"path": "website/src/program"} // @end ], "files": [] }
在注释 @inplate
和 @plate
之间就是内容片段的 handlebars 模板:
{{#each nonRootTSProjectPaths}} {"path": "{{this}}"}{{#unless @last}},{{/unless}} {{/each}}
@plate
和 @end
之间则是会被自动更新的内容片段。
这里缺失的一块儿是变量 nonRootTSProjectPaths
,我们将通过 inplate 的配置文件 inplate.config.js 提供:
const Path = require('path'); const Glob = require('glob'); const nonRootTSProjectConfigPaths = Glob.sync('*/**/tsconfig.json', { ignore: '**/node_modules/**', dot: true, }); const nonRootTSProjectPaths = nonRootTSProjectConfigPaths.map(path => Path.dirname(path), ); module.exports = { 'tsconfig.json': { data: { nonRootTSProjectPaths, }, }, };
这样一来,我们就可以通过执行 inplate --update
来更新 tsconfig.json 中的项目引用了:

在 CI 中,则可以使用 inplate --assert
命令确认当前相关配置文件没有需要修改的地方。
Inplate 支持多种注释风格和使用方式,生成内容后会自动使用 prettier 进行格式化(如果有安装和配置), 请移步 项目主页 了解更多。
如果你正在维护的项目中,也有类似的情况,inplate 或许可以是一个趁手的小工具:
- 项目引用、文件、文件夹列表维护(结合 Glob 等小工具)。
- 环境变量列表维护(通过 mock 配置文件中的相关方法调用获取)。
- 同步代码片段到文档(结合 ts-morph 等小工具)。
- 等等。
如果有任何使用问题,也欢迎评论或者通过 issue 告诉我们。
Makeflow(makeflow.com)让团队经验可以像文档一样详细地记录在流程中,指导和验证工作实践。每一次经验的迭代都可以通过任务的执行自然“推送”到整个团队,消除工作流程从想法到实践、从实践到改进之间的多种障碍。大到产品迭代管理,小到监控报警处置:记录、实践、再记录,把每一次进步写入团队基因——延续、变化、可复制。