解释在 grunt 中实现语言维度 sitemap

解读

面试官想知道你是否能把“多语言站点地图”这一SEO刚需落地到 Grunt 的自动化流程里。核心考点有三层:

  1. 如何按语言维度拆分页面清单(zh、en、ja…);
  2. 如何用 Grunt 插件生成符合 Google 多语言规范的 sitemap.xml(含 xhtml:link 的 hreflang 条目);
  3. 如何把生成过程嵌入现有构建管线,保证每次上线前自动刷新,避免人工遗漏。
    国内项目普遍要兼顾百度与 Google,百度不认 hreflang,但仍需一份无语言标记的主 sitemap;Google 需要带 hreflang 的独立文件。因此方案必须一次生成两套,并自动提交到搜索引擎站长平台。

知识点

  • grunt-sitemap-xml:官方维护的 sitemap 生成插件,支持自定义模板,可注入 hreflang 逻辑。
  • grunt-i18n-extract:社区插件,可扫描模板/路由文件,按语言维度输出页面列表 JSON。
  • grunt-template:用 Lodash 模板把 JSON 渲染成符合规范的 XML。
  • hreflang 规则:同一 URL 只能指向一种语言,返回码 200,且需双向确认(zh 页面指向 en,en 页面也必须指回 zh)。
  • 国内 CDN 缓存:生成后必须主动 ping 百度与 Google 的 ping 接口,否则新 URL 延迟收录。
  • Gruntfile 任务链:clean → i18n_extract → template → sitemap → ping → watch,保证开发阶段增量更新

答案

  1. 安装依赖
    npm i -D grunt-sitemap-xml grunt-i18n-extract grunt-template grunt-contrib-clean grunt-contrib-watch

  2. 在 Gruntfile 里配置语言维度数据源
    先用 grunt-i18n-extract 扫描 src/pages 下的 {lang}/**/*.ejs,输出 tmp/lang-map.json,格式:
    {
    "zh": ["/", "/product"],
    "en": ["/en/", "/en/product"],
    "ja": ["/ja/", "/ja/product"]
    }

  3. 用 grunt-template 把 lang-map.json 渲染成中间 XML 片段
    模板片段(sitemap-hreflang.tmpl):
    <% zh.forEach(url=>{ %>
    <url>
    <loc>https://example.com<%= url %></loc>
    <xhtml:link rel="alternate" hreflang="zh" href="https://example.com<%= url %>"/>
    <xhtml:link rel="alternate" hreflang="en" href="https://example.com/en<%= url %>"/>
    <xhtml:link rel="alternate" hreflang="ja" href="https://example.com/ja<%= url %>"/>
    </url>
    <% }) %>

  4. 用 grunt-sitemap-xml 合并片段并生成最终文件
    配置:
    sitemap_xml: {
    dist: {
    options: {
    siteRoot: 'https://example.com',
    srcFiles: ['tmp/hreflang-*.xml'],
    dest: 'dist/sitemap.xml'
    }
    }
    }

  5. 生成后自动 ping
    在任务尾部加自定义 task:
    grunt.registerTask('ping', function(){
    const https=require('https');
    ['baidu', 'google'].forEach(engine=>{
    https.get(https://ping.baidu.com/ping/RPC2?sitemap=https%3A%2F%2Fexample.com%2Fsitemap.xml);
    });
    });

  6. 完整任务链
    grunt.registerTask('sitemap-i18n', ['clean:tmp', 'i18n_extract', 'template', 'sitemap_xml', 'ping']);

执行 grunt sitemap-i18n 即可一次性产出带 hreflang 的多语言 sitemap,并通知搜索引擎,零人工干预

拓展思考

  • 若页面量级过万,需按语言拆分子 sitemap,用 Grunt 动态生成 sitemap-index.xml,并在 robots.txt 中声明。
  • 对于服务端渲染(SSR)项目,可把 Grunt 任务作为上线前钩子,在 Jenkins/GitLab CI 里调用,确保版本回滚时 sitemap 同步回退
  • 国内百度小程序要求单独的 sitemap.txt,可在同一任务链里再插一个子任务,用 grunt-contrib-concat 把 URL 列表输出为纯文本,一份构建,三份产出