你的TypeScript网站,爬虫真的能看懂吗?
你刚用TypeScript写完一个漂亮的商品详情页,热更新秒出效果,类型提示精准到让人感动。但等你发到线上,打开Google Search Console一看:首页被收录了,点进去的12个SKU页面,只抓到了3个——剩下那些,爬虫连“加载中…”都没等到。
不是代码写得不好,是爬虫根本没机会读到你想让它读的内容。
TypeScript编译到底会不会影响SEO?
TypeScript本身对SEO完全透明。它不运行,也不发请求,只是帮你把代码写得更稳。真正被爬虫看到的,永远是你构建后输出的JavaScript文件。
关键在编译配置。比如tsconfig.json里设"target": "es5",TypeScript会把箭头函数、解构、async/await全转成冗长的var _this = this;式写法。生成的JS体积变大、逻辑嵌套更深,爬虫解析时要多走几道弯。
而设成"target": "es2015"或更高,代码更接近你写的原意:const { name, price } = product; 这种结构,爬虫一眼就能识别变量含义和数据流向。
有家做小众乐器的站,把TS编译目标从es5切到es2015后,产品页的JS体积瘦了一半。他们没动任何业务逻辑,但两周后,新上架的尤克里里型号在搜索结果里出现得更快了——评论区动态加载的内容,第一次被完整抓取进索引。
单页应用(SPA)是爬虫友好的最大障碍吗?
问题不在TypeScript,而在你选的架构。
如果你用React/Vue/Angular + TypeScript搭的是纯客户端渲染的SPA,那服务器返回的HTML里,可能只有这样一行:
<div id="root"></div>
剩下的所有商品图、价格、规格表,全靠app.chunk.js下载、执行、挂载才出来。Googlebot虽然能跑JS,但它不会等你3秒、5秒,也不会反复重试失败的chunk加载。它抓一次,没内容就走了。
更现实的情况是:首页能进,二级分类页勉强进,点进具体某款吉他参数页?404一样安静。不是链接坏了,是爬虫压根没拿到那个页面的HTML骨架。
如何配置TypeScript和构建工具,让输出对爬虫更友好?
别想着“教爬虫读懂TS”,重点是让最终产出的JS更轻、更直、更容易被一次性加载成功。
编译目标优先选新标准
tsconfig.json里,把"target"从"es5"换成"es2015"或"es2017"。如果用户还有一批IE11流量,可以单独配一个兼容包,但主包别妥协。关掉不必要的polyfill
检查"lib"数组,删掉"dom"以外你实际用不到的库(比如"es2015.reflect")。每多一个,打包体积就多一丢丢不可控的代码。让JS文件“分得更细”
用Vite或Webpack时,打开路由级代码分割。比如用户访问/guitars/acoustic,只加载acoustic-page.js,而不是整个app.bundle.js。爬虫不用下几百KB再找关键内容。压缩要狠,混淆要慎
Terser默认压缩足够。但别开mangle: {toplevel: true}这种全局变量名混淆——把productPrice变成a,对爬虫理解页面语义没帮助,反而可能干扰它对数据上下文的判断。
之前有个开发者团队,只调了Vite的build.rollupOptions.output.manualChunks,把商品详情页相关逻辑单独打成product-detail.js。上线后,Search Console里该页面的“已抓取但未索引”状态少了大半。
除了编译,还有哪些必须做的SEO适配?
TypeScript再优雅,也救不了一个空HTML壳子。你得主动给爬虫喂“熟食”,而不是扔生米过去。
首选SSR或预渲染
Next.js(React)、Nuxt(Vue)、Angular Universal这些框架,能直接在Node层把TypeScript组件吐成带真实内容的HTML。用户打开快,爬虫进来就见货——标题、描述、商品图、参数表,全在源码里。
每个页面都要有独立的<title>和<meta name="description">
别让所有路由共用一个<title>My App</title>。用next/head或vue-meta动态注入。爬虫靠这个判断页面主题,也是用户在搜索结果里第一眼看到的东西。
生成并提交sitemap.xml
用next-sitemap或@nuxtjs/sitemap这类插件,自动把所有带getStaticPaths或getServerSideProps的页面列进地图。别手写,也别漏掉分页后的/products?page=2这种URL。
加一段JSON-LD结构化数据
在页面HTML里塞进类似这样的代码:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Martin D-28 吉他",
"offers": { "@type": "Offer", "price": "12999" }
}
</script>
这是你直接告诉搜索引擎:“这就是个商品,名字叫什么,卖多少钱”的最简方式。
如何测试和验证爬虫看到的真实内容?
别猜,直接看。
打开Google Search Console → “网址检查” → 输入你最想被收录的商品页URL。点“请求索引”前,先点“查看已抓取的网页”。它会给你一张截图,和底下完整的HTML源码。
重点看两点:
- 截图里有没有商品图、价格、购买按钮?
- HTML源码里,
<div class="price">¥12,999</div>这种关键信息是不是已经存在?还是只有<div id="root"></div>?
再补一道测试:Chrome里打开你的网站,按F12 → 右上角三个点 → More tools → Rendering → 勾选“Disable JavaScript”。刷新页面。如果只剩白屏或“Loading…”,说明你还没跨过爬虫友好这条线。
有家摄影器材站就是这么发现的:新品发布页禁用JS后,首页导航还在,但所有新品卡片全消失了。他们当天就给这个路由加了getStaticProps,第二天Search Console里抓取成功率就从32%跳到89%。
今天下班前就能执行的一个具体操作
打开你的项目根目录,找到tsconfig.json。
定位到compilerOptions.target这一行。
如果值是"es5",把它改成"es2017"(兼容性够广,代码够干净)。
保存,然后运行npm run build(或yarn build、pnpm build,看你用哪个)。
构建完,随便挑一个核心商品页URL,去Google Search Console的“网址检查”里粘贴、测试。对比修改前后的“已抓取的网页”截图——这次,商品标题和价格应该直接躺在HTML里了。
改完这一步,你不需要重写框架,也不用学新工具。但爬虫第一次来,就能看清你最想让它看见的东西。