1.前言
由于公司需要把首页进行seo排名,但是首页已经完成好,并且还是hash模式,要做成seo排名,不能有hash模式的#,同时要能读取到渲染好的页面.所以,针对这2点困难,最终想到的解决方案是:
- 先hash需要转换为history,保证是无#的美观模式;
- 需要做到提前渲染好,可以采取vue的SSR,spa预渲染或nuxt.js.
2.选取渲染方式
首先,hash转换为history已经是板上钉钉的事情,这时候就开始找快捷简单改动少的渲染方式,分别有vue的SSR,spa和nuxt.js.
- vue项目提供了ssr的方案.不过ssr方案需要在node上调用
renderToString
来渲染。如果不介意在系统结构中增加一层node
的话,就可以使用ssr的方式,这种方式会改变前后端交互的方式。ssr文档.改动中等 - spa预渲染,即使用prerender-spa-plugin插件预渲染.由于页面较少,且预渲染相对于SSH比较简单,于是选择预渲染页面,预渲染可以极大的提高网页访问速度。而且配合一些meat插件,基本可以满足SEO需求。改动在三者中最小
- Nuxt就是基于Vue的一个应用框架,采用服务端渲染,让你的SPA应用(Vue)也可以拥有SEO.官方文档,但是由于需要重新改变底层框架,改动在三者中最大.
综上所述,选择第二个方式,spa预渲染,改动小,同时也能达到seo的要求
3.hash转为history
1.模式修改 (目录:src/router/index.js)
// mode:'hash',
mode: 'history',
base: '/',
2.相对路径调整
2.1 目录:build/webpack.prod.conf.js
//history为"/",hash:'./'
//publicPath:'./',
publicPath:'/',
2.2目录:config/index.js
// histroy模式:"/" ,hash模式:"./"
//assetsPublicPath: './',
assetsPublicPath: '/',
2.3 修改原因:
./ 是指用户所在的当前目录(相对路径);
/ 是指根目录(绝对路径,项目根目录),也就是项目根目录;
对于hash模式,根路径是固定的,就是项目的根目录,但是history模式下,以/
开头的嵌套路径会被当作根路径,所以使用“./”引入文件,就会找不到文件了,因为文件本身就是在项目根目录下的,并不在嵌套路径这个目录下。
总结,无论hash模式还是history模式,可以直接使用“/”从项目根目录引入静态文件。
3.服务端修改
nginx配置: 参考官网教程
location / {
proxy_pass http://127.0.0.1:80;
root /usr/local/tomcat/tomcat_xhcf/webapps/ROOT; #表明路径
index index.html index.htm;
try_files $uri $uri/ /index.html; #交给index.html处理
}
原因:这样修改,避免了刷新404的问题,因为如果URL匹配不到任何静态资源,就跳转到默认的index.html进行处理.
4.SPA预渲染
1.安装prerender-spa-plugin
npm i -s prerender-spa-plugin
或者 (淘宝镜像)
cnpm i --save prerender-spa-plugin
2.配置
2.1目录:build/webpack.prod.conf.js
在plugins列表里,加入下面代码:
// 在vue-cli生成的文件的基础上,只有下面这个才是我们要配置的
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname, '../dist'),
// 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。这里很重要,需要把自己想要生成静态文件的路由全部写进去。
routes: [
'/',
'/about',
],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event',
//时间
renderAfterTime:5000
})
})
2.2目录:src/main.js (mounted是新增代码,对应build/webpack.prod.conf.js里加的)
/* 记得要通过 router 配置参数注入路由,从而让整个应用都有路由功能*/
const app =new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
/* 这句非常重要,否则预渲染将不会启动 */
mounted () {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
最终npm run build ,生成代码,目录如下即成功
dist
│ ├── about
│ └── index.html
│
├── index.html
└── static
5.全程操作概览
1.修改完以上全部配置;
2.项目里npm run build生成文件,放入对应服务器目录;
3.nginx重启配置:
nginx -t #测试配置是否正确
nginx -s reload #重启nginx配置
大功告成!
博主个人博客网站:奇想派的个人博客
本文原创作者:奇想派、一名努力分享的程序员。
文章首发平台:微信公众号【编程达人】
原创不易!各位小伙伴觉得文章不错的话,不妨关注公众号,进行点赞(在看)、转发三连走起!谢谢大家!