使用 grunt-cloudflare 清除指定 URL 缓存

解读

在国内前端工程化面试中,**“如何自动化刷新 CDN 缓存”**是高频考点。
面试官真正想考察的是:

  1. 你是否理解 Grunt 插件生态的接入方式
  2. 能否把 Cloudflare 国内版(百度云加速、京东云等) 的缓存刷新动作无缝嵌入 CI;
  3. 是否具备 密钥安全管理失败重试 意识,而不是简单跑通命令。
    答得太浅(只贴配置)会被追问“生产环境如何区分域名”“失败如何报警”;答得太深(扯到边缘规则、Worker)又容易超纲。因此要把 “Gruntfile 层调用、环境变量层隔离、错误处理层兜底” 三板斧讲全,才能拿到高分。

知识点

  1. grunt-cloudflare 内部调用 Cloudflare v4 API: POST /zones/:zone_identifier/purge_cache,需一次性传入 files 数组
  2. 国内备案域名需先 双域名映射www.example.cnwww.example.com),Grunt 任务里要动态拼接 https 协议头,否则 400;
  3. 密钥必须走 环境变量(CF_EMAIL、CF_KEY、CF_ZONE_ID),禁止写死到仓库,否则安全审计直接挂;
  4. 由于云厂商对 单账号 QPS 限制 1200/5min,任务里要加 throttle 与重试退避,否则 CI 并发时会 429;
  5. Grunt 任务失败默认不会阻断后续流程,需手动 grunt.fail.fatal 并在 GitLab-CI 里设置 allow_failure: false,确保缓存未清成功就中断部署;
  6. 对多页面应用,“只清 HTML 入口,不清静态资源” 是性价比最高的策略,需在 files 数组里用 通配符负向排除(!.js / !.css)。

答案

  1. 安装与版本锁定
npm i -D grunt-cloudflare@2.1.0
# 固定版本,避免 CF API 升级导致字段漂移
  1. 环境变量注入(GitLab-CI 示例)
variables:
  CF_EMAIL: "ci@yourcompany.cn"
  CF_KEY: "$CLOUDFLARE_GLOBAL_KEY"   # 在 GitLab 设置里 masked
  CF_ZONE_ID: "$ZONE_ID_CN"          # 国内备案域名的 zoneId
  1. Gruntfile.js 关键片段
module.exports = function(grunt) {
  grunt.initConfig({
    cloudflare: {
      options: {
        email:  process.env.CF_EMAIL,
        key:    process.env.CF_KEY,
        zoneId: process.env.CF_ZONE_ID,
        // 失败重试 3 次,退避 2s
        retry: 3,
        retryDelay: 2000
      },
      prod: {
        // 只清首页与主入口,静态资源带 hash 无需清
        files: [
          'https://www.example.cn/',
          'https://www.example.cn/index.html',
          'https://www.example.cn/about.html'
        ]
      }
    }
  });

  grunt.loadNpmTasks('grunt-cloudflare');

  // 注册阻塞式任务,失败即中断部署
  grunt.registerTask('cf-purge', function() {
    const done = this.async();
    grunt.util.spawn({
      grunt: true,
      args: ['cloudflare:prod']
    }, (err, res) => {
      if (err || res.code !== 0) {
        grunt.fail.fatal('Cloudflare 缓存刷新失败,部署已终止');
      }
      grunt.log.ok('CDN 缓存已清');
      done();
    });
  });
};
  1. 在 CI 的 deploy 阶段调用
script:
  - grunt build
  - grunt cf-purge   # 只有清缓存成功才继续
  1. 运行效果
$ grunt cf-purge
>> Running cloudflare:prod
>> Purge 3 URLs ✔
>> CDN 缓存已清

拓展思考

  1. 灰度刷新:把 URL 列表拆成 10% 流量白名单,先用 Cloudflare API 的 purge_cache_prefix/v2/prefix/*,观察 5min 无 404 再全量清,降低回源压力;
  2. 密钥轮转:利用腾讯 SSM 或阿里云 KMS 的“凭据轮转”功能,把 CF_KEY 设置 30 天过期,CI 每次运行时先 ssm get-secret,实现 0 人工干预
  3. 边缘规则联动:若项目接入了 Cloudflare Worker 做 A/B,清缓存后需调用 purge_cache_tags,把 __version=123 标签一并失效,否则用户仍可能命中旧 Worker 脚本;
  4. 国产化替代:百度云加速 API 与官方 CF 不兼容,可封装一个 grunt-baiducloud-cdn 插件,把同样接口抽象成 cloudflare: 多目标,实现“一份配置,多云刷新”;
  5. 监控闭环:在 cf-purge 任务后追加一个 curl -I 探测,确认 CF-Cache-Status: MISS 出现次数等于 URL 数,再把指标推送到 夜莺监控,实现“缓存刷新可观测”。