jingzhiMo.github.io
jingzhiMo.github.io copied to clipboard
简单折腾一下 prerender-spa-plugin
背景
网站的首页和部分介绍页面需要预渲染,为了更好的SEO;而网站的dashboard的相关页面则保持原来的SPA处理。后续生产环境的文件构建需要放到ci统一处理。
使用工具
- prerender-spa-plugin
- puppeteer
现在使用prerender-spa-plugin
的插件用来把部分静态页面预渲染,这个插件是依赖puppeteer
的工具,puppeteer
工具是需要下载一个chromium
的浏览器。如果没有梯子是没办法下载的,下载安装包的大小大概在70M左右。
puppeteer
从1.7.0
版本开始就把puppeteer-core
的包分离出来,如果需要单独测试的话,仅下载这个包就好了。但是prerender-spa-plugin
插件是依赖puppeteer
的包,所以需要设置npm的环境变量才能能够跳过下载浏览器,在安装npm install
之前,需要在项目的根目录新建文件.npmrc
或者往里面追加内容,内容是:
puppeteer_skip_chromium_download=true
使用基础例子
后面所使用的代码,均基于官方的例子进行更改
webpack 配置
在webpack的配置当中,生产环境的plugins的数组需要加入下面的实例:
// 引入对应的插件
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
module.exports = {
// ...
plugins: [
// ...
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/', '/about', '/contact' ],
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
// 这个事件名称需要与网站的事件名称一直,具体可以参考官方例子:
// https://github.com/chrisvfritz/prerender-spa-plugin/tree/master/examples/vue2-webpack-router
renderAfterDocumentEvent: 'render-event',
// 这个是macos下chrome的调用路径
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
// chromium的调用路径
// executablePath: '/Applications/Chromium.app/Contents/MacOS/Chromium'
})
})
]
}
vue-cli 配置
如果使用vue-cli
进行配置,需要更改vue.config.js
,可以通过configureWebpack
的函数进行处理:
// vue.config.js
module.exports = {
configureWebpack: () => {
// 针对生产环境进行处理
if (process.env.NODE_ENV === 'production') {
return {
plugins: [
new PrerenderSPAPlugin({
// ...
})
]
}
}
}
}
使用本地浏览器
在使用本地系统安装浏览器的时候,推荐使用chromium,由于部分情况chrome可能会出现问题。linux通常chrome和chromium的安装路径分别是:
/usr/bin/chromium-browser
/usr/bin/google-chrome
部分chrome版本是stable版本,所以可能是/usr/bin/google-chrome-stable
;在linux可以通过which
命令查看对应路径,然后把得到的路径填入executablePath
字段即可。
在linux系统执行的时候,有可能会出现依赖没有装完,导致无法启动chromium,这个问题可以查看这个解决方案;也有可能会提示配置不需要沙箱环境,需要改动配置如下:
new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/', '/about', '/contact' ],
renderer: new Renderer({
inject: {
foo: 'bar'
},
headless: false,
renderAfterDocumentEvent: 'render-event',
// 这个是macos下chrome的调用路径
executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
// 配置这行
args: ['--no-sandbox']
})
})
ci 环境部署
如果需要在ci环境部署,浏览器的安装也是一个问题,浏览器的安装包体积也不小,这里想到的几个方案有:
- 不跳过安装chromium,直接在
node_modules
安装的时候,把浏览器安装包也下载了;然后ci的cache
把node_modules
加上; - 跳过安装chromium,自行下载浏览器并安装浏览器,
cache
需要把node_modules
和浏览器下载路径都缓存; - 跳过安装chromium,选用一个带有
chromium
的docker的image,就可以避免安装chromium。
缺点:
1、2两点都能够通过不同方法安装浏览器,但是通常浏览器依赖包还是缺失,需要自行安装对应的依赖;
第3点应该是比较好的解决方案,但需要选中一个比较好且稳定的image,dockerhub