- 安装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文件夹,把这个里面的静态资源复制一份放在和它同级的目录下即可!