如何为 Grunt 项目编写可检索的架构决策记录(ADR)

解读

在国内前端团队面试中,面试官问“怎么给 Grunt 项目写可检索的 ADR”,并不是想听 ADR 的理论定义,而是考察三件事:

  1. 你是否把 Grunt 构建链路与架构决策绑定——即每一次插件升级、任务拆分、目录调整都要留下决策痕迹;
  2. 你是否让记录可检索——面对 4000+ 插件、多人协作、CI 历史,能否 5 秒内定位某次决策;
  3. 你是否用低成本工具链落地——国内项目节奏快,不能为了写文档而写文档,必须和现有 Git、npm、Jenkins、Confluence 无缝衔接。
    答不到这三点,会被认为“只会配任务,不会保传承”。

知识点

  1. Grunt 生态决策高频场景:插件选型(grunt-contrib-uglify vs. grunt-terser)、任务粒度(一个 Gruntfile 还是按模块拆成 grunt/*.js)、目录规范(src/dist 还是 pages/build)、性能策略(grunt-newer、grunt-concurrent、持久缓存)、私有仓库(cnpm、verdaccio 镜像源)。
  2. ADR 四段式模板:标题、上下文(Context)、决策(Decision)、后果(Consequences),必须加“Grunt 标签”与“插件版本号”,方便后期 grep。
  3. 可检索落地手段
    • 文件命名YYYY-MM-DD-grunt-插件名-决策关键词.md,例如 2023-07-06-grunt-terser-es6-target.md
    • 统一目录/docs/adr/ 平铺,拒绝多级文件夹,减少搜索深度;
    • 前置元数据:在 Markdown 顶部加 YAML 头,包含 grunt-pluginversionauthorissue,配合 git log --grep=grunt-plugin:terser 秒级回溯;
    • 索引脚本:在 package.json 加 "adr:index": "ls docs/adr | grep grunt > docs/grunt-adr-index.txt",每次 CI 自动生成索引,Jenkins 归档成构建产物,新人克隆项目即可见全貌;
    • 中文关键词:国内团队用中文搜索,必须在正文重复一次英文插件名,例如“使用 grunt-contrib-clean 清理构建目录”,兼顾中英文检索。
  4. 评审与失效机制:任何 PR 若改动 Gruntfile 或新增插件,必须同时在 /docs/adr/ 新增或修改 ADR,并在 Pull Request Template 里打钩;ADR 失效后把状态改为 Superseded保留原文件,只追加后缀 -superseded,确保历史链路不断裂。

答案

示范一份可直接落地的 Grunt ADR,供面试时口述或白板书写:

文件名:2023-07-06-grunt-terser-es6-target.md

---
grunt-plugin: grunt-terser
version: 1.0.0
author: zhangsan
issue: JIRA-1234
status: Accepted
---

# 使用 grunt-terser 替代 grunt-contrib-uglify 以支持 ES6 压缩

## 上下文
- 源码已迁移到 ES6,grunt-contrib-uglify@4.x 仍基于 uglify-js 2,无法压缩 async/await,导致线上报错。  
- 团队构建机使用 Node 14,cnpm 镜像源同步滞后,需锁定插件版本。  

## 决策
1. 采用 grunt-terser@1.0.0,底层依赖 terser 5,**完全支持 ES6+ 语法**;  
2. 保留原 uglify 任务配置字段,**仅替换插件名**,降低迁移成本;  
3. 在 Gruntfile.js 中新增子任务 `terser:legacy`,**同时输出 ES5 兼容包**,供旧版 CMS 引用;  
4. 私有 cnpm 源提前缓存 terser 包,**CI 构建耗时增幅 < 5%** 视为可接受。  

## 后果
+ 正向:压缩后 bundle 体积减少 3.2%,SourceMap 定位列号准确;  
- 负向:terser 并行压缩占满 4 核,本地 watch 阶段风扇噪音增大,**后续引入 grunt-concurrent 限制并发数**;  
- 风险:若 terser 后续版本破坏 API,**需再次评审 ADR 并更新状态为 Superseded**。  

面试时补充一句:“我们把该文件路径写进 Jenkins Pipeline,构建失败时自动打印相关 ADR 标题,开发 5 秒就能知道背景,减少扯皮。” 这句话一出,面试官基本认定你既懂 Grunt 又懂工程化传承。

拓展思考

  1. 大型 Monorepo 如何扩展:当 Grunt 任务分散在 packages/* 时,在根目录维护 /docs/adr/grunt-index.md,用脚本聚合所有子包 ADR,统一版本号前缀,防止重复命名;
  2. 与前端规约仓库联动:把 ADR 元数据同步到内部知识库(语雀/Confluence),利用 Webhook 自动生成“Grunt 插件选型图谱”,面试可提到“让 HR 也能搜到技术决策”,体现跨部门影响力;
  3. 渐进式迁移到 Vite/Webpack:若未来要废弃 Grunt,新增 ADR 状态“Deprecated”,并在 Gruntfile 首行注释链接到迁移 ADR,实现“链式考古”,面试官会认可你对技术债的敬畏;
  4. 度量指标:在 ADR 后果段落预埋可量化数据(构建耗时、包体积、CPU 占比),下次绩效评审用数据说话,把枯燥文档变成可度量的业务价值,面试时抛出这一点,可瞬间拉高视野。