- 安装prerender-spa-plugin
yarn add prerender-spa-plugin
或
npm install prerender-spa-plugin
初始配置 后面记录踩的坑
- 配置路由
const routes = [{path: '/',redirect: {path: '/HomeView'},},{path: '/home',redirect: {path: '/HomeView'},},{ path: '/HomeView',component: HomeView},{path: '/CompanyProfile',component: CompanyProfile},{path: '/ConsultationChannel',component: ConsultationChannel},{path: '/IndustryIntroduction',name: 'IndustryIntroduction',component: IndustryIntroduction,},{path: '/ProductIntroduction',name: 'ProductIntroduction',component: ProductIntroduction,},{path: '/ProductsServices',name: 'ProductsServices',component: ProductsServices,},{path: '/CompanyCulture',name: 'CompanyCulture',component: CompanyCulture,},{path: '/CompanyAbout',name: 'CompanyAbout',component: CompanyAbout,},{path: '/CompanyIntroduction',name: 'CompanyIntroduction',component: CompanyIntroduction,},
]const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes,
})
- vue.config.js配置
const PrerenderSPAPlugin = require('prerender-spa-plugin');
const Renderer = PrerenderSPAPlugin.PuppeteerRenderer;module.exports = {// 服务器环境production 本地环境development // "../" 其他配置无法打包publicPath: process.env.NODE_ENV === "production" ? "../" : "./",// 在npm run build 或 yarn build 时 ,生成文件的目录名称(要和baseUrl的生产环境路径一致)(默认dist)outputDir: 'home',configureWebpack: config => {if (process.env.NODE_ENV !== 'production') return;return {plugins: [new PrerenderSPAPlugin({// 生成文件的路径,这里使用了相对路径staticDir: path.join(__dirname, 'home'),// 需要进行预渲染的路由,这里需要根据你的实际路由配置来设置routes: [ '/', '/HomeView', '/CompanyProfile', '/ConsultationChannel', '/IndustryIntroduction', '/ProductIntroduction', '/ProductsServices', '/CompanyCulture', '/CompanyAbout', '/CompanyIntroduction'],// 渲染器配置,这里使用 Puppeteer 渲染renderer: new Renderer({inject: {foo: 'bar'},// 在渲染之前等待一定时间,以确保 SPA 中的异步操作完成renderAfterTime: 5000,headless: false,// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。renderAfterDocumentEvent: 'render-event'})})]}}
}
遇到的问题
- publicPath配置为…/后, 在服务器静态资源和路由加载找不到子路径的目录,publicPath改为真实的子路径后无法build 不加publicPath静态文件访问存在问题
解决
此问题解决出处
publicPath: process.env.NODE_ENV === "production" ? '/home/' : "./",,outputDir: path.join(__dirname, "./home", "/home/"),configureWebpack: config => {if (process.env.NODE_ENV !== 'production') return;return {plugins: [new PrerenderSPAPlugin({// 生成文件的路径,这里使用了相对路径staticDir: path.join(__dirname, 'home/'),indexPath: path.join(__dirname, "home/home/index.html"), //重要// 需要进行预渲染的路由,这里需要根据你的实际路由配置来设置routes: [ '/', '/HomeView', '/CompanyProfile', '/ConsultationChannel', '/IndustryIntroduction', '/ProductIntroduction', '/ProductsServices', '/CompanyCulture', '/CompanyAbout', '/CompanyIntroduction'],// 渲染器配置,这里使用 Puppeteer 渲染renderer: new Renderer({inject: {foo: 'bar'},// 在渲染之前等待一定时间,以确保 SPA 中的异步操作完成renderAfterTime: 5000,headless: false,// 在 main.js 中 document.dispatchEvent(new Event('render-event')),两者的事件名称要对应上。renderAfterDocumentEvent: 'render-event'})})]}}
- 升级到服务器后,在使用 prerender-spa-plugin 进行预渲染处理时,如果手动刷新 Vue 路由后路径末尾会出现 /,通常这是由于浏览器的默认行为导致的,特别是在使用 history 模式的 Vue 路由时比较常见。这种行为可能会影响到预期的路由匹配和渲染
解决
- Vue Router 中设置 strict: true,这样在路由跳转时会自动去掉末尾的斜杠,避免不必要的重定向。
const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes,
})
- 在路由的 beforeEnter 钩子中,可以检查并处理路径末尾的斜杠,确保它符合预期的路由结构。
const routes = [{path: '/',redirect: {path: '/HomeView'},},{ path: '/HomeView',component: HomeView,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/CompanyProfile',component: CompanyProfile,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/ConsultationChannel',component: ConsultationChannel,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/IndustryIntroduction',name: 'IndustryIntroduction',component: IndustryIntroduction,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/ProductIntroduction',name: 'ProductIntroduction',component: ProductIntroduction,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/ProductsServices',name: 'ProductsServices',component: ProductsServices,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/CompanyCulture',name: 'CompanyCulture',component: CompanyCulture,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/CompanyAbout',name: 'CompanyAbout',component: CompanyAbout,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},{path: '/CompanyIntroduction',name: 'CompanyIntroduction',component: CompanyIntroduction,beforeEnter: (to, from, next) => {if (to.path.endsWith('/')) {next({ path: to.path.slice(0, -1) });} else {next();}}},]
- 在以上问题处理完后,升级到服务器后,静态资源访问不到
资源访问不到
http://ip:port/home/static/css/app.e2f5f186.css
解决
打包生成home文件夹,在home文件夹下还有一个home文件夹,把这个里面的静态资源复制一份放在和它同级的目录下即可!