记录Vite项目多页面应用模式踩坑

Posted swag_特约男演员

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录Vite项目多页面应用模式踩坑相关的知识,希望对你有一定的参考价值。

如何配置多页应用¿

vite官网-多页面应用模式
Vite Vue3 多页面开发环境路由重定向
VUE3.0+Vite 多页面应用配置

案例目录结构

第一个坑:环境变量undefined

如果你按照vite官方的目录结构配置的多页应用,没有改动root路径,则不会出现这个问题。如果你的root改为src/那这个envDir也是一样的,因为它默认是root。此时如果你的.env .env.production .env.development还在外面即和vite.config.js同级则不对,因为它不在root下,所以此时读取环境变量是undefined
解决方法:把环境变量移至你指定的root

第二个坑:子页面路由刷新丢失

跳转到子页面/subPage/是正常的,刷新路由也不丢失。
跳转到子页面/subPage/list,刷新路由就会丢失,如果你配置了路由守卫,则会触发跳转/404

为什么¿

history模式就是vite开发服务器把浏览器的url当成后端路由/subPage/它能找到/subPage/index.html。所以/subPage/的主页没错。/subPage/list找不到这个资源,vite开发服务器已经内部处理好了返回/index.html。这个其实是不正确的index.html,导致路由丢失。换成hash模式是没问题的,如/subPage/#/list。浏览器不会把#后面的当作后端路由,不会去发送请求,资源由前端处理。

怎么办¿

知道原因了,就好办了。当我们发现以/subPage/开头的url找不到资源时,给它返回/subPage/index.html,这个就是子页面入口,返回这个就能找到资源。

我把前端打包放到自己写的node服务器上,验证得出:这样解决是对的。

但是在开发环境怎么解决呢?不解决开发时就像有蚂蚁在身上爬,老鼠在咬指甲盖。当然你可以用hash模式

既然node可以解决,当然vite也可以,因为vite开发服务器就是node。但是貌似要自己写个插件,但是我不会。可以去插件社区里找,幸运的是我找到了。
vite插件社区

vite-plugin-mpa-plus
More flexible MPA (multi-page application) supports html templates, path rewriting.
翻译一下:更多扩展的多页应用,支持html模板和路径重写

这一看就是我要的啊,跟着文档试试。

import  fileURLToPath, URL  from 'node:url'
import  resolve  from 'path'
import  defineConfig  from 'vite'
import mpaPlugin from 'vite-plugin-mpa-plus'
import type  Rewrite, Pages  from 'vite-plugin-mpa-plus'
import vue from '@vitejs/plugin-vue'

const rewrites: Array<Rewrite> = [ from: /\\/subPage/, to: '/subPage/index.html' ]
const pages: any | Pages = [
  
    entry: resolve(__dirname, './src/main.ts'),
    filename: resolve(__dirname, './src/index.html'),
    template: resolve(__dirname, './src/index.html'),
    inject: 
      data: 
        title: 'mpa'
      
    
  ,
  
    entry: resolve(__dirname, './src/subPage/main.ts'),
    filename: resolve(__dirname, './src/subPage/index.html'),
    template: resolve(__dirname, './src/subPage/index.html'),
    inject: 
      data: 
        title: 'mpa'
      
    
  
]

// https://vitejs.dev/config/
export default defineConfig(
  root: resolve(__dirname, './src'),
  publicDir: resolve(__dirname, 'public'),
  plugins: [
    vue(),
    mpaPlugin(
      pages,
      historyApiFallback: 
        rewrites
      
    )
  ],
  resolve: 
    alias: 
      '@': fileURLToPath(new URL('./src', import.meta.url))
    
  ,
  build: 
    outDir: resolve(__dirname, './dist'),
    emptyOutDir: true,
    rollupOptions: 
      input: 
        main: resolve(__dirname, './src/index.html'),
        sub: resolve(__dirname, './src/subPage/index.html')
      
    
  ,
  server: 
    open: true
  
)

这下开发环境下的多页应用history模式路由也不丢失了。

react-踩坑记录——页面底部多出一倍高度的空白

挂载slider组件后页面底部多出一倍高度的空白,如下:

slider组件内容⬇️:

class Slider extends Component{
  constructor(){
    super();
  }
  componentDidMount(){
    var index = 0;
    setInterval(function () {
        index++;
        if(index>3)
        {
          index=0;
          $(\'.list\').css(\'left\',\'0\');
        }
        $(\'.contain .list\').animate({\'left\':index*-375 },1000)
    },3000);
  }
  render(){
    return <div className="contain">
            <ul className="list">
              {
                this.props.slide_img.map((item,index)=>{
                  return <li key={index}><img className=\'list_img\' src={item.src} alt=\'图片加载失败\'></img></li>
                })
              }
            </ul>
          </div>
        }
}

css样式⬇️:

.contain{
    width: 400%;
    height: 295px;
    margin: 0 auto;
    position: relative;
    overflow: hidden;
}
.list{
    width: 100%;
    height: 295px;
    position: absolute;
    left: 0px;
}
.list>li {
    float: left;
    width: 25%; 
    height: 100%;
}
.list_img {
    display: block;
    height: 100%;
    width: 100%;
} 

解决方法:针对根组件添加样式设置⬇️

#root{
    width: 100%;
    height: 100%;
    overflow: scroll;
}                  /*即index.html文件中根组件div的id值为root*/
.contain{
    width: 400%;
    height: 295px;
    margin: 0 auto;
    position: relative;
    overflow: hidden;
}
.list{
    width: 100%;
    height: 295px;
    position: absolute;
    left: 0px;
}
.list>li {
    float: left;
    width: 25%; 
    height: 100%;
}
.list_img {
    display: block;
    height: 100%;
    width: 100%;
} 

成功解决⬇️

 

以上是关于记录Vite项目多页面应用模式踩坑的主要内容,如果未能解决你的问题,请参考以下文章

vue(vite)项目架构

vue3中vite的配置

vite2 + vue3实现curd:路由跳转

Vite+Vue3+Vue-Router@4+Pinia 快速起步

vue3+vite2+element-plus+ts搭建一个项目

分析vite2.x/rollup分包原理,解决chunk碎片问题