預渲染模式
預渲染prerender-spa-plugin配置生成多頁面,解決首屏白屏問題,提升用戶體驗。同時配合 vue-meta-info 可以生成title和meta標簽,可解決SPA頁面的SEO痛點
一、安裝
npm install prerender-spa-plugin --save
二、路由模式
特別注意:使用預渲染vue-router必須使用history模式
// 路由配置如下:
export default new Router({
mode: 'history', // 將mode的值修改為history
routes: [
// 根路徑
{
path: '/',
redirect: '/index',
component: Index
},
// 首頁
{
path: '/index',
component: Index
},
// 發現
{
path: '/find',
component: Find
},
// 訂單
{
path: '/order',
component: Order
}
]
})
三、webpack配置
注意:如果使用的是vue-cli,則必須是在build中的webpack.prod.conf.js文件中添加配置,這樣在執行打包命令npm run build時才會生效
webpack.prod.conf.js添加以下配置:
1、引入prerender-spa-plugin插件
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer
2、添加插件
// 在webpack的plugin中添加:
// 在vue-cli生成的文件的基礎上,下面這個才是我們要配置的
new PrerenderSPAPlugin({
// 生成文件的路徑,也可以與webpakc打包的一致。
// 這個目錄只能有一級,如果目錄層次大于一級,在生成的時候不會有任何錯誤提示,在預渲染的時候只會卡著不動。
staticDir: path.join(__dirname, '../dist'),
// 對應自己的路由文件,比如index有參數,就需要寫成 /index/param1。
routes: ['/', '/find', '/order', ],
// 這個很重要,如果沒有配置這段,也不會進行預編譯
renderer: new Renderer({
inject: {},
// 在 main.js 中 document.dispatchEvent(new Event('render-event')),兩者的事件名稱要對應上。
renderAfterDocumentEvent: 'render-event',
args: ['--no-sandbox', '--disable-setuid-sandbox']
})
})
四、修改main.js入口文件
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>',
// 添加mounted,不然不會執行預編譯
mounted () {
document.dispatchEvent(new Event('render-event'))
}
})
按照以上步驟完成配置后,執行 npm run build
,可以在dist目錄中,看到webpack配置的需要預渲染的幾個頁面,如下圖:
五、遇到的問題:
按照上面的步驟配置了以后,抱著試一試的心態執行了npm run build
,結果不出意外的掛了,小樣,就猜到不會這么順利的.....
下面就是報的錯誤:
bogon:vue-meituan admin$ npm run build
vue-meituan@1.0.0 build /Users/admin/Desktop/vue-meituan
node build/build.js
? building for production...
Starting to optimize CSS...
Processing static/css/app.0363d93c8c31fa94640cb54cec450bb6.css...
Processed static/css/app.0363d93c8c31fa94640cb54cec450bb6.css, before: 78372, after: 71744, ratio: 91.54%
? building for production...==========
/Users/admin/Desktop/vue-meituan/node_modules/puppeteer/.local-chromium/mac-599821/chrome-mac/Chromium.app/Contents/MacOS/Chromium
Error: Chromium revision is not downloaded. Run "npm install" or "yarn install"
at Launcher.launch (/Users/admin/Desktop/vue-meituan/node_modules/puppeteer/lib/Launcher.js:115:15)
[Prerenderer - PuppeteerRenderer] Unable to start Puppeteer
? building for production...(node:8028) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'close' of null
at PuppeteerRenderer.destroy (/Users/admin/Desktop/vue-meituan/node_modules/@prerenderer/renderer-puppeteer/es6/renderer.js:140:21)
at Prerenderer.destroy (/Users/admin/Desktop/vue-meituan/node_modules/@prerenderer/prerenderer/es6/index.js:87:20)
at PrerendererInstance.initialize.then.then.then.then.then.then.then.then.catch.err (/Users/admin/Desktop/vue-meituan/node_modules/prerender-spa-plugin/es6/index.js:144:29)
(node:8028) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:8028) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
? building for production...^C
好家伙,一堆密密麻麻的,看著眼花,仔細看看,關鍵就是下面這句標紅的地方:
必須指定版本的 chromium 才能使用 puppeteer
Error: Chromium revision is not downloaded
. Run "npm install" or "yarn install"
at Launcher.launch (/Users/admin/Desktop/vue-meituan/node_modules/puppeteer/lib/Launcher.js:115:15)
[Prerenderer - PuppeteerRenderer] Unable to start Puppeteer
解決辦法:
經查閱資料,在一篇文章上,找到了一個快捷的辦法下載更新合適的Chromium版本。
使用淘寶鏡像,下載puppeteer,可以代理下載 Chromium r526987
cnpm install puppeteer
參考
https://www.sunzhongwei.com/use-the-puppeteer-automation-chrome-chromium-operation
https://blog.csdn.net/qq_42606051/article/details/82529376
https://juejin.im/post/5bee7dd4e51d451f5b54cbb4