vue預渲染prerender-spa-plugin解決首屏白屏問題

Eline發表於2018-11-26

預渲染模式 預渲染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配置的需要預渲染的幾個頁面,如下圖:

image.png

五、遇到的問題:

按照上面的步驟配置了以後,抱著試一試的心態執行了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

解決辦法:

經查閱資料,在一篇文章上,找到了一個快捷的辦法下載更新合適的Chromium版本。

使用淘寶映象,下載puppeteer,可以代理下載 Chromium r526987
cnpm install puppeteer
複製程式碼

參考

www.sunzhongwei.com/use-the-pup… blog.csdn.net/qq_42606051… juejin.im/post/5bee7d…

相關文章