对一个网站来说,seo是非常重要的一块内容。最近用vue做了一个网站,很自然地找到了Vue SSR 指南。我做的网站只有几个注重营销的页面需要seo,发现在这种场景下用prerender-spa-plugin
做下预渲染就够了。后面在具体实践中遇到了些问题,现记录下。
首先是由于baseUrl填的cdn的地址,如果打包是在本地的话,这时预渲染时会请求cdn上的资源,很自然是返回404找不到资源。
解决方案是使资源打包后就能通过cdn访问,目前条件限制,只能在本地打包,只能采用笨方式,先打包一遍,这时是没做好预渲染的,然后上传资源到cdn后,再打包一次做预渲染。
2018.09.18更新
上面这种方式不可取,其实还有些方式。
- 本地绑定host
这种方式简单,但是有不确定因素,如果在集成环境中,修改hosts可能不太方便。
- 动态重定向cdn地址到本地
给源项目发了个pr。
终于做好预渲染了,但这时发现初始页面有内容但没有样式,过了会才有样式,导致有一个明显的闪现。原因在于页面做了代码分离,当前页面的chunk并非初始chunk,所以当前页面的css在页面中是prefetch,优先级比较低。
解决方案是识别出当前页面依赖的css,并把rel="prefetch"改成rel="stylesheet"。
先给chunk加上chunkName,以方便后面的识别
const routes = [
{ path: '/', component: () => import(/* webpackChunkName: "home" */ './controller/home.vue') },
{ path: '/qa', component: () => import( /* webpackChunkName: "qa" */ './controller/qa.vue') },
{ path: '/pay/callback', component: () => import('./controller/pay-success.vue') },
{ path: '/order/list', component: () => import('./controller/order.vue') },
{ path: '/pages/log2', component: () => import('./controller/login.vue') },
]
复制代码
然后通过prerender-spa-plugin
的postProcess选型替换下rel="prefetch"
postProcess (context) {
const pathToChunkNameMap = {
'/': 'home',
'/qa': 'qa'
}
const chunkName = pathToChunkNameMap[context.route]
if (!chunkName) {
return context
}
const reg = new RegExp('(' + chunkName + '\\.[a-zA-Z0-9]+\\.css") rel="prefetch"')
context.html = context.html.replace(reg, ($1, $2) => {
return $2 + ' rel=stylesheet'
})
return context;
},
复制代码