当前位置: 首页 > 工具软件 > spa-server > 使用案例 >

vue3 seo prerender-spa-plugin swiper6 vue-router4 build 打包空白 图片压缩

郭俊拔
2023-12-01

版本依赖

vue3、vue-cli4、 vue-router4、swiper6、prerender-spa-plugin3、image-webpack-loader7


  "dependencies": {
    "core-js": "^3.6.5",
    "image-webpack-loader": "^7.0.1",
    "prerender-spa-plugin": "^3.4.0",
    "swiper": "^6.8.4",
    "vue": "^3.0.0",
    "vue-router": "4.0.3"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "~4.5.0",
    "@vue/cli-plugin-eslint": "~4.5.0",
    "@vue/cli-service": "~4.5.0",
    "@vue/compiler-sfc": "^3.0.0",
    "babel-eslint": "^10.1.0",
    "eslint": "^6.7.2",
    "eslint-plugin-vue": "^7.0.0"
  }

vue-router 4 打包后路由不显示,浏览器一片空白的问题

  1. 路由未设置成 hash 模式,将路由设置成哈希模式
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
    history: createWebHashHistory(process.env.VUE_APP_ROUTER),
    routes: [...]
})
export default router
  1. 忽略 ,错误很蠢,但也不排除
<template>
  <div>
    <router-view></router-view>
  </div>
</template>
  1. 引用组件文件时没加 vue后缀

    调试时不会报任何错,build 后页面全空白 ,浏览器后台还会报错

    解决:路由引用组件加上vue后缀

import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [{
    path:'/', 
    name: 'moblie',
    component: ()=> import('../page/Moblie.vue')
    // ../page/Moblie 不加 .vue 就会有这个问题
}]
const router = createRouter({
    history: createWebHashHistory(process.env.VUE_APP_ROUTER),
    routes
})
export default router
4.路由设置 base 路径的问题
export default new Router({
  mode: 'history',// history hash
  base:'/dist/',
  routes:[...]
})
服务器 http:// .... /dist/index.html 空白
服务器 http:// .... /dist/ 正常

veu.config 配置

seo 优化

spa 单页面应用泪点,不考虑复杂服务器交互,可用 prerender-spa-plugin

vue3 prerender-spa-plugin 也可以用

yarn add prerender-spa-plugin@3.4.0

首次使用可用会下载 谷歌浏览器,yarn serve 启动项目,会开启一个谷歌浏览器窗口,中途可能弹出360拦截,全部允许

在弹出浏览器上点刷新,应该就没事了,之后每次 yarn serve 会多一些 prerender-spa-plugin 的信息

在vue.config 添加配置

const PrerenderSPAPlugin = require('prerender-spa-plugin');
const path = require('path');
module.exports = {
    publicPath: "./", 打包改了 这的路径,就没办法 seo
    configureWebpack: config => {
        return {
            plugins: [
                new PrerenderSPAPlugin({
                    staticDir: path.join(__dirname, 'dist'),
                    routes: ['/', '/computer'],
                    renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
                        renderAfterTime: 5000
                    }),
                    // 通过这的方法改路径
                    postProcess (renderedRoute) {
                            renderedRoute.html = renderedRoute.html.replace(/="static\//gi, `="./static/`)
                        return renderedRoute
                    }
                })
            ]
        }
    }
}

vue3 main 文件 配置 prerender-spa-plugin

import {createApp} from 'vue' 
import App from './App.vue'
import router from './router/routers'
const app = createApp(App)
app.use(router)
app.use({mounted () {
    document.dispatchEvent(new Event('render-event'))
  }})
app.mount('#app')

routes: [’/’, ‘/computer’] 就是路由指代的路径

const router = createRouter({
    history: createWebHashHistory(process.env.VUE_APP_ROUTER),
    routes:[{
        path:'/', 
        name: 'moblie',
        component: ()=> import('../page/Moblie.vue')
    },{
    	path:'/computer', 
        name: 'computer',
        component: ()=> import('../page/Computer.vue')
    }]
})

配置成功后,yarn build ,index.html 会看到 html标签

图片压缩

原始的vue项目图片不会自动压缩,image-webpack-loader 插件可自动配置压缩图片,vue3 可用

yarn add image-webpack-loader@7.0.1 
配置vue.config
module.exports = {
    chainWebpack: config => {
    config.module
        .rule('images')
        .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options({
            bypassOnDebug: true
        })
        .end()
    }
}

总的配置如下


const PrerenderSPAPlugin = require('prerender-spa-plugin');
const path = require('path');
module.exports = {
    publicPath: "./", // 公共路径(必须有的)
    outputDir: "dist", // 输出文件目录
    assetsDir: "static", //静态资源文件名称
    lintOnSave: false,
    productionSourceMap: false, //去除打包后js的map文件
    devServer: { //启动项目在8080端口自动打开
        open: true,
        port: 8090,
        proxy: null
    },
    configureWebpack: config => {
        if(process.env.NODE_ENV === "production"){
            config.optimization.minimizer.map((arg) => {
                console.log("--------",path.dirname)
                const option = arg.options.terserOptions.compress;
                option.drop_console = true; // 打开开关
                return arg;
            });
        }
        return {
            plugins: [
                new PrerenderSPAPlugin({
                    staticDir: path.join(__dirname, 'dist'),
                    routes: ['/', '/computer'],
                    renderer: new PrerenderSPAPlugin.PuppeteerRenderer({
                        renderAfterTime: 5000
                    })
                })
            ]
        }
    },
    chainWebpack: config => {
    config.module
        .rule('images')
        .test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
        .use('image-webpack-loader')
        .loader('image-webpack-loader')
        .options({
            bypassOnDebug: true
        })
        .end()
    }
}

路由配置 vue-router4

main 文件
import {createApp} from 'vue' 
import App from './App.vue'
import router from './router/routers'
const app = createApp(App)
app.use(router)
app.use({mounted () {
    document.dispatchEvent(new Event('render-event'))
  }})
app.mount('#app')

router 文件

createWebHashHistory 哈希路由 createWebHistory

import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [{
    path:'/', 
    name: 'moblie',
    component: ()=> import('../page/Moblie.vue')
},{
    path:'/computer', 
    name: 'computer',
    component: ()=> import('../page/Computer.vue')
},{
    path:'/:w+', 未设置路径走这
    name: 'notfound',
    component: ()=> require('../page/NotFound')
}]
const router = createRouter({
    history: createWebHashHistory(process.env.VUE_APP_ROUTER),
    routes
})
export default router

路由传值

<template>
  <div>
    <router-view></router-view>
  </div>
</template>
<script>
<script>
import {useRouter} from 'vue-router' // 引用
export default {
  name: 'App',
  components: {  },
  data(){
    return { }
  },
  setup(){
    // 路由
    let router = useRouter()
    let Agents = ['android','iphone','Windows Phone','iPad']
    let url = navigator.userAgent.toLowerCase()
    let ismobile = false
    for(let i=0;i<Agents.length;i++){
      if(url.indexOf(Agents[i].toLowerCase()) !== -1){
        ismobile = true
        break
      }
    } // 传值两个都可 router.push({path: '/moblie',query: {device: "success"}})
    if(ismobile) router.push({name: 'moblie',params: {device: "success"}})
    else router.push({name: 'computer',params: {device: 'success'}})
  },
  created(){}
}
</script>

路由 接收值

import {useRoute} from 'vue-router'
let route = useRoute()
route.params 
route.query 

vue3 使用 swiper

安装

yarn add swiper@6.8.4
全局使用

加载 scss 官方用import,加载css 用 require,不然打包不会显示 swiper css

import {createApp} from 'vue' 
import App from './App.vue'
import SwiperCore, {Navigation, Pagination} from 'swiper'
require('swiper/swiper.min.css') ;
require('swiper/components/pagination/pagination.min.css')  
require('swiper/components/navigation/navigation.min.css')  
SwiperCore.use([Navigation, Pagination])
const app = createApp(App)
app.mount('#app')

简单例子

<template>
    <div>
    	<swiper
            :slides-per-view="1"
            :space-between="0"
            navigation
            pagination
            @swiper="onSwiper"
            @slideChange="onSlideChange"
        >
            <swiper-slide ></swiper-slide>
            <swiper-slide></swiper-slide> .....
        </swiper>
    </div>
</template>
<script>
import { Swiper, SwiperSlide } from 'swiper/vue';
export default{
	components:{
        Swiper,
        SwiperSlide
    },
    methods:{
        onSwiper(swiper){
            console.log(swiper);
        },
        onSlideChange(slide){
            console.log('slide change',slide.pagination);
        }
    }
}
</script>
 类似资料: