解释在 grunt 中实现语言维度 sitemap
解读
面试官想知道你是否能把“多语言站点地图”这一SEO刚需落地到 Grunt 的自动化流程里。核心考点有三层:
- 如何按语言维度拆分页面清单(zh、en、ja…);
- 如何用 Grunt 插件生成符合 Google 多语言规范的 sitemap.xml(含 xhtml:link 的 hreflang 条目);
- 如何把生成过程嵌入现有构建管线,保证每次上线前自动刷新,避免人工遗漏。
国内项目普遍要兼顾百度与 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,保证开发阶段增量更新。
答案
-
安装依赖
npm i -D grunt-sitemap-xml grunt-i18n-extract grunt-template grunt-contrib-clean grunt-contrib-watch -
在 Gruntfile 里配置语言维度数据源
先用 grunt-i18n-extract 扫描 src/pages 下的{lang}/**/*.ejs,输出tmp/lang-map.json,格式:
{
"zh": ["/", "/product"],
"en": ["/en/", "/en/product"],
"ja": ["/ja/", "/ja/product"]
} -
用 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>
<% }) %> -
用 grunt-sitemap-xml 合并片段并生成最终文件
配置:
sitemap_xml: {
dist: {
options: {
siteRoot: 'https://example.com',
srcFiles: ['tmp/hreflang-*.xml'],
dest: 'dist/sitemap.xml'
}
}
} -
生成后自动 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);
});
}); -
完整任务链
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 列表输出为纯文本,一份构建,三份产出。