🌵前言
开发一个官网项目,由于使用传统的多页面开发模式,不利于做优化。
🎄预渲染
通过使用 prerender-spa-plugin 生成静态页面,既提高了页面渲染的速度,也利于 seo,使用方式如下
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
module.exports = {
plugins: [new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/' ], // 需要预渲染的路由,
renderer: new Renderer({
headless: true, // 开启无头浏览器
renderAfterDocumentEvent: 'render-event', // 渲染的事件,只有触发了这个事件,插件才会开始爬取html
}),
})]
}
// 在 App.vue 中调用如下方法,事件名称和 renderAfterDocumentEvent 保持一直,其他框架在类似的生命周期调用即可
export default {
mounted() {
document.dispatchEvent(new Event('render-event'));
}
};
踩坑记录
Unable to prerender all routes!
在mac下设置了 headless: false 导致提示 Unable to prerender all routes! google 了一堆,告诉我说不能使用路由懒加载,其实造成这个报错的原因有很多,我是设置了headless: true 就好了

静态资源使用了cdn
由于使用了cdn,但是我们还没有发布,所以cdn上并没有对于的资源,导致页面加载失败(终端会一直卡住没反应)
这个的解决办法,google一搜也有很多的解决办法,比较好的办法就是使用代理,将cdn地址代理到本地。
我看了几篇文章,都是重新用node起一个代理服务,其实 prerender-spa-plugin 本身就可以设置代理。
只需要将代理服务起的端口号改成80,并且修改本机host中127.0.0.1的映射就可以实现代理,这样设置以后,请求 xxx.cdn.com/static/1.txt 就等于 127.0.0.1/static/1.txt
具体代码如下:
// webpack.config.js
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;
const path = require('path');
module.exports = {
plugins: [new PrerenderSPAPlugin({
staticDir: path.join(__dirname, 'dist'),
routes: [ '/' ], // 需要预渲染的路由,
renderer: new Renderer({
headless: true, // 开启无头浏览器
renderAfterDocumentEvent: 'render-event', // 渲染的事件,只有触发了这个事件,插件才会开始爬取html
}),
+ server: {
+ port: 80, // 设置端口为80
+ proxy: {
+ '/static: {
+ target: `http://localhost`,
+ changeOrigin: true,
+ pathRewrite: {
+ '^/static': '/'
+ }
+ }
+ }
+ }
})]
}
现在只有最后一步了,修改host这个操作总不能每次手动来吧,我们现在写一个node脚本帮我们做这个事情
// build.js
const util = require('util');
const exec = util.promisify(require('child_process').exec);
const hostile = require('hostile');
const cdnDomain = 'xxx.cdn.com';
process.env.FORCE_COLOR = true; // 开启控制台打印的颜色
hostile.set('127.0.0.1', cdnDomain, async () => {
const { stdout, stderr } = await exec('vue-cli-service build');
console.log(stdout);
console.log(stderr);
hostile.remove('127.0.0.1', cdnDomain, () => process.exit(0));
});
最后 node build.js 完成打包
代理了cdn带来的问题
本来以为已经完美解决cdn的问题了,但是当我们某些资源在cdn中存在,而在本地不存在,使用代理反而会出现问题。
我遇到的问题是这样的,为了优化代码的体积,将 vue vue-router swiper 等依赖外置,使用cdn的方式引入,而我本地却没有这些文件。由于修改了host,已经没有其他办法在访问到cdn上的资源了。
最终的解决办法很笨,在 public 文件夹中存放这些文件,保证通过代理也能访问到,然后使用 git 忽略这部分文件,避免发布出去。