原理: 在webpack中使用 prerender-spa-plugin 插件将要预渲染的文件打包生成到dist,在构建阶段生成匹配预渲染路径的 html 文件(注意:每个需要预渲染的路由都有一个对应的
html)。构建出来的 html 文件已有部分内容。
一、安装依赖
1、删除node_modules包
2、执行命令 npm config set puppeteer_download_host https://storage.googleapis.com.cnpmjs.org (ps:别问我为啥执行这个命令,因为国内下载不了puppeteer,vue预渲染打包会遇到 Chromium revision is not downloaded 报错)
3、执行 npm install
4、执行 npm install prerender-spa-plugin --save --ignore-scripts
二、vue.config.js (ps:cli3.0以下版本目录不一样,请自行修改对应文件)
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' }) }), ], }; } }
staticDir:代码打包目录
indexPath:模板页面
routes:要预渲染的页面路由
inject:默认挂在window.__PRERENDER_INJECTED对象上,可以通过window.__PRERENDER_INJECTED.foo在预渲染页面取值
headless:渲染时显示浏览器窗口。对调试很有用。
renderAfterDocumentEvent:等到事件触发去渲染,此处我理解为是Puppeteer获取页面的时机
renderAfterDocumentEvent 这个则很关键,这个是监听 document.dispatchEvent
事件,决定什么时候开始预渲染。需要在钩子函数中触发事件,如
三、修改main.js文件,监听在webpack定义的事件
四、修改路由模式为history
router.js 中设置mode: “history”
预渲染的单页应用路由需要使用 History 模式而不是 Hash 模式。原因很简单,Hash 不会带到服务器,路由信息会丢失。vue-router 启用 History 模式参考这里。
五、运行npm run build
看一下生成的 dist 的目录里是不是有每个路由名称对应的文件夹。然后找个 目录里 的 index.html 用IDE打开,看文件内容里是否有该文件应该有的内容。有的话,就设置成功了