Vue-cli使用prerender-spa-plugin插件预渲染和配置cdn
参考:https://www.jianshu.com/p/6a4c0b281e7f
使用vue-cli打包项目一般为spa项目,众所周知单页面应用不利于SEO,有ssr和预渲染两种解决方案,这里我们只讨论预渲染。
此教程使用的prerender-spa-plugin版本和vue版本
vue-cli有2.0和3.0版本,解决方法是不一样的,这里我们要分开讨论。
vue-cli3.0版本
3.0的cli看上去简洁多了,去掉了2.0 build和config等目录,那我们怎么去修改webpack的配置呢?
在根目录下创建vue.config.js,进行你的配置。
1.安装
cnpm install prerender-spa-plugin --save
2.vue-config.js中增加
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
module.exports = {
configureWebpack: config => {
if (process.env.NODE_ENV !== 'production') return;
return {
plugins: [
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
// 下面这句话非常重要!!!
// 这个目录只能有一级,如果目录层次大于一级,在生成的时候不会有任何错误提示,在预渲染的时候只会卡着不动。
staticDir: path.join(__dirname,'dist'),
// 对应自己的路由文件,比如a有参数,就需要写成 /a/param1。
routes: ['/', '/product','/about'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
}),
],
};
}
}
3.在main.js中增加
new Vue({
router,
store,
render: h => h(App),
mounted () {
document.dispatchEvent(new Event('render-event'))
}
}).$mount('#app')
4.router.js 中设置mode: “history”
5.运行npm run build,看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了,如果没成功,照着上面的步骤再来一次!!!
vue-cli2.0版本
1.安装
cnpm install prerender-spa-plugin --save
2.webpack.prod.conf.js增加部分代码
const path = require('path')
const PrerenderSPAPlugin = require('prerender-spa-plugin') //引用插件
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
const webpackConfig = merge(baseWebpackConfig, {
plugins: [
// vue-cli生成的配置中就已有这个了,不要动
new HtmlWebpackPlugin({
filename: config.build.index,
template: 'index.html',
inject: true,
minify: {
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
},
chunksSortMode: 'dependency'
}),
// 配置PrerenderSPAPlugin
new PrerenderSPAPlugin({
// 生成文件的路径,也可以与webpakc打包的一致。
staticDir: path.join(__dirname, '../dist'),
// 对应自己的路由文件,比如index有参数,就需要写成 /index/param1。
routes: ['/', '/product','/about','/contact','/join','/jzjh'],
// 这个很重要,如果没有配置这段,也不会进行预编译
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。
renderAfterDocumentEvent: 'render-event'
})
})
]
})
3.在main.js中增加
new Vue({
el: '#app',
router,
render: h => h(App),
mounted () {
document.dispatchEvent(new Event('render-event'))
}
})
4.router.js 中设置mode: “history”
5.运行npm run build,看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了,如果没成功,照着上面的步骤再来一次!!!
特别提醒
1.vue-cli2.0和3.0的设置大致一致,但有一个很不同
在3.0中,设置staticDir: path.join(__dirname,'dist'),
在2.0中,设置staticDir: path.join(__dirname,'../dist'),
如果你把3.0的staticDir设置为path.join(__dirname,'../dist')或者把2.0的staticDir设置为path.join(__dirname,'dist'),运行npm run build 都会报错,这要特别注意!!!
2.细心的小伙伴会发现,不管2.0还是3.0都需要设置 history 模式,那这一步是否是必须的呢?经过测试,如果不设置history模式,其实也能运行和生成文件的,但查看每个index.html文件的内容都会是一样的。所以这一步是必须的
如果你想修改每个页面的meta 信息,这里推荐使用 vue-meta
如何再静态生成的如:indexl.html的html文件图片等使用我们配置的cdn环境呢?
1.src目录下增加文件public-path.js
/**
* CDN
*/ const isPrerender = window.__PRERENDER_INJECTED__ === 'prerender' __webpack_public_path__ = isPrerender ? '' : process.env.CDN_PATH
2.main.js引入public-path.js,注意要在最开头的地方添加
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import './public-path'
import Vue from 'vue'
import App from './App'
import router from './router'
import VueMeta from 'vue-meta'
import $ from 'jquery'
import 'babel-polyfill'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'
import 'swiper/dist/css/swiper.css';
Vue.config.productionTip = false
Vue.use(VueMeta)
new Vue({
el: '#app',
router,
render: h => h(App),
mounted() {
document.dispatchEvent(new Event('render-event'))
}
})
3.修改webpack.pro.conf.js文件
// 配置PrerenderSPAPlugin
new PrerenderSPAPlugin({
staticDir: config.build.assetsRoot,
routes: [ '/' ],
outputDir: path.join(config.build.assetsRoot, config.build.assetsPublicPath),
indexPath: path.join(config.build.assetsRoot, 'index.html'),
postProcess (renderedRoute) {
// add CDN
let cdnPath = JSON.parse(env.CDN_PATH);
renderedRoute.html = renderedRoute.html.replace(
/(<script[^<>]*src=\")((?!http|https)[^<>\"]*)(\"[^<>]*>[^<>]*<\/script>)/ig,
`$1${cdnPath}$2$3`
).replace(
/(<link[^<>]*href=\")((?!http|https)[^<>\"]*)(\"[^<>]*>)/ig,
`$1${cdnPath}$2$3`
).replace(/(<img[^<>]*src=\")((?!http|https|data:image)[^<>\"]*)(\"[^<>]*>)/ig,
`$1${cdnPath}$2$3`) return renderedRoute
}, renderer: new Renderer({
injectProperty: '__PRERENDER_INJECTED__',
inject: 'prerender',
renderAfterDocumentEvent: 'render-event',
})
}),
注意红色字体的,把相对路径的img和js加上我们的cdn路径
Vue-cli使用prerender-spa-plugin插件预渲染和配置cdn的更多相关文章
- HTML5 VUE单页应用 SEO 优化之 预渲染(prerender-spa-plugin)
前言:当前 SPA 架构流行的趋势如日中天,前后端分离的业务模式已经成为互联网开发的主流方式,但是 单页面 应用始终存在一个痛点,那就是 SEO, 对于那些需要推广,希望能在百度搜索时排名靠前的网站而 ...
- vue cli 解决跨域 线上 nginx 反向代理配置
前后分离 axios 接 api 跨域问题如图: 解决办法: 1. npm start 本地开发环境解决: 在webpack配置文件 /config/index.js 里找到 proxyTable 开 ...
- 什么是服务端渲染、客户端渲染、SPA、预渲染,看完这一篇就够了
服务端渲染(SSR) 简述: 又称为后端渲染,服务器端在返回html之前,在html特定的区域特定的符号里用数据填充,再给客户端,客户端只负责解析HTML. 鼠标右击点击查看源码时,页 ...
- prerender-spa-plugin预渲染踩坑
为什么要使用预渲染? 为了应付SEO(国内特别是百度)考虑在网站(vue技术栈系列)做一些优化.大概有几种方案可以考虑: 服务端做优化: 第一,ssr,vue官方文档给出的服务器渲染方案,这是一套完整 ...
- 用prerender-spa-plugin插件Vue项目优化SEO做ssr服务端渲染及预渲染
今天在做公交的时候没干,用手机看看文章,偶然发现了一个关于Vue优化seo的文章,我先是在Vue的官方文档看了一篇关于Vue做SEO优化的文章. 上面提到了nuxt.js这个框架,这个框架我做过一个小 ...
- vue项目使用 prerender-spa-plugin 预渲染
由于项目要做seo优化,而用vue写成的spa页面谷歌浏览器等是抓取不到数据的.介于ssr和预渲染来说,后者相对来说要简单许多.所以采用了预渲染方式.采用插件prerender-spa-plugin使 ...
- Vue项目预渲染机制引入实践
周末想顺便把已经做好静态页面的webApp项目做一下SEO优化,由于不想写蹩脚的SSR代码,所以准备采用预渲染,本来想着网上有这么多预渲染的文章,随便找个来跟着做不就完了嘛,结果年轻的我付出了整个周末 ...
- vue cli 3
介绍 Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统 通过 @vue/cli 搭建交互式的项目脚手架. 通过 @vue/cli + @vue/cli-service-global 快 ...
- Vue项目预渲染机制
我们知道SPA有很多优点,不过一个缺点就是对(不是Google的)愚蠢的搜索引擎的SEO不友好,为了照顾这些引擎,目前主要有两个方案:服务端渲染(Server Side Rendering).预渲染( ...
随机推荐
- SQL回顾1
1.学生表Student(SID,Sname,Sage,Ssex) --SID 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 2.课程表 Course(CID,Cname,T ...
- apache2 配置入门
ServerRoot "/usr/local/apache2" #服务器根目录 Listen #监听端口 语法格式为Listen [IP地址:]端口 [协议],其中IP地址与协议为 ...
- 单例设计模式(Singleton)的优化
单例模式的优化 单例模式懒汉式写法,单例模式的优化有以下四个方面: 使用同步保证线程安全synchronized 使用volatile关键字:volatile关键字提醒编译器后面所定义的变量随时都有可 ...
- JavaWeb(一):Java技术概览
一.Java技术体系 在早期,Java被称为Java开发工具包或JDK,是一门与平台(由一组 必需的API组成)紧密耦合的语言. 从1998年底的1.2版本开始,Java技术栈被分割为下面关键部分: ...
- MySQL提示:too many connections
1.首先查询最大连接数 show variables like '%max_connections%'; 2.检查当前的连接情况: show processlist; 3.批量kill当前的连接: 通 ...
- CDH6.3.1安装hue 报错
x 一.查看日志server运行日志 /var/log/cloudera-scm-server/cloudera-scm-server.log 2019-12-11 17:28:34,201 INFO ...
- npm 是干什么的?(非教程)
看了之后就很清楚什么叫NPM,以后它是干嘛的.谢谢楼主 网上的 npm 教程主要都在讲怎么安装.配置和使用 npm,却不告诉新人「为什么要使用 npm」.今天我就来讲讲这个话题. 本文目标读者是「不太 ...
- Python3解leetcode Isomorphic Strings
问题描述: Given two strings s and t, determine if they are isomorphic. Two strings are isomorphic if the ...
- PHP 利用 curl 发送 post get del put patch 请求
因为需要在 php 开发中对接其它接口需要用 php curl 去对接其它接口 我把他们封装成函数 希望能对大家有所帮助. 这里面是封装好的会自动把 data 进行转成 json 格式,同时解码成 p ...
- Xcode cannot run using the selected device after upgrade
Please follow below step 1>Go to Project Build setting 2>Change compiler for c/c++/objective c ...