使用 grunt-license-finder 生成依赖许可证清单
解读
在国内前端团队面试中,“合规”与“安全” 已成为必考维度。grunt-license-finder 并不是高频插件,但面试官借它考察三点:
- 你是否能把“合规风险”纳入构建流程,而非事后补票;
- 是否熟悉 Grunt 多任务(multi-task) 机制与动态任务注册;
- 能否把产出物(license.json)无缝接入CI 门禁与制品库审计。
题目看似简单,实则要求你给出“可落地、可集成、可审计”的完整方案,而不是跑通一次命令。
知识点
- grunt-license-finder 本质:对 npm/yarn/pnpm 安装的依赖树执行
license-checker,再按 Grunt File 规范输出 JSON/CSV/HTML; - Grunt 任务阶段:
initConfig → registerTask → grunt.loadNpmTasks,需理解任务管道顺序; - 国内镜像场景:淘宝镜像、华为云镜像可能导致
license-checker拿不到repository字段,需兜底策略(自定义 transform); - CI 集成:在 GitLab-CI 或 Jenkins 中,把生成的
license-summary.json作为**制品(artifact)**上传,供法务扫描; - 合规红线:GPL-3.0、CC-BY-NC 等传染性或商业受限许可证需触发失败阈值,用
--failOn参数或自定义 reporter 抛出 exit code=1; - 性能优化:monorepo 项目依赖量大,需用
--excludePrivate与--onlyunknown过滤,避免 5min+ 的扫描阻塞; - 缓存策略:把
node_modules/.cache/license目录缓存到 GitLab runner,二次构建提速 70%。
答案
- 安装与版本锁定
npm i -D grunt-license-finder@~4
# 锁定小版本,防止 5.x 破坏性变更
- Gruntfile.js 配置(可直接拷贝到企业脚手架)
module.exports = function(grunt) {
grunt.initConfig({
license_finder: {
options: {
// 国内镜像兼容:强制离线扫描,不发送 github api 请求
offline: true,
// 只关心生产依赖,过滤 dev 包
production: true,
// 自定义输出格式,方便后续脚本解析
customFormat: {
name: '',
version: '',
licenses: '',
repository: '',
licenseFile: ''
},
// 合规红线:出现 GPL-3.0 直接失败
failOn: ['GPL-3.0', 'GPL-2.0'],
// 输出路径,必须放到 CI 制品目录
out: 'dist/reports/license-summary.json'
},
src: ['./'] // 扫描当前项目根
}
});
grunt.loadNpmTasks('grunt-license-finder');
// 注册合规门禁任务
grunt.registerTask('compliance', ['license_finder']);
// 默认构建链路插入合规检查
grunt.registerTask('default', ['clean', 'eslint', 'compliance', 'webpack']);
};
- GitLab-CI 片段(符合国内私有化部署)
compliance:
stage: security
script:
- npm ci --registry=https://registry.npmmirror.com
- npx grunt compliance
artifacts:
reports:
license: dist/reports/license-summary.json
expire_in: 90 days
only:
- merge_requests
- master
- 本地验证
grunt compliance --debug
# 若出现 GPL-3.0,终端 exit code=1,MR 被 GitLab 拒绝
拓展思考
- 双引擎备份:若 grunt-license-finder 后续无人维护,可快速切换至
license-webpack-plugin或vite-plugin-license,但需统一输出格式,保证法务系统无感切换; - SBOM 升级:国内监管正在对标《网络安全审查办法》,下一步需把 license.json 转成 SPDX 标准,再上传至国家互联网应急中心接口;
- 微前端场景:主应用 + 多个子应用独立仓库,需在构建基座时聚合所有子应用 license 文件,用
grunt-contrib-concat合并为单一视图,避免“许可证碎片化”风险; - 性能极限:当依赖超过 5k 包时,可先用
pnpm licenses list --json生成缓存,再让 grunt-license-finder 增量扫描,把耗时从 180s 降到 20s; - 合规左移:在 husky pre-push 阶段增加
grunt compliance,提前拦截不合规依赖,减少 MR 被驳回带来的代码冻结成本。