Vue3+Vite+TS+Eslint(Airbnb规则)搭建生产项目,踩坑详记(终章):vite配置多入口,多页面应用

11,857 阅读6分钟

本文已参与好文召集令活动,点击查看:后端、大前端双赛道投稿,2万元奖池等你挑战!

vue3搭建生产项目终于来到了终章,不过在这里要跟大家说一声抱歉,经过慎重考虑,决定阉割掉vue-router引入的部分,因为vue-router的引入除了初始化方法和history模式和以前有些区别外,其它地方大同小异,所以大家可以自己根据文档引入vue-router。

本系列前四篇文章传送门:

为什么需要多入口

在我们的生产项目中,系统的用户前台和管理后台放在了同一个代码仓库进行管理,这样两者可以共享系项目公共配置。但其实两个端之间基本没有业务关联,也不需要互相跳转,因此也没必要采用微前端那一套东西,更何况微前端是拆分仓库并且有强关联的项目采用的组织方式。

所以是否要使用多入口模式,需要我们根据实际的业务场景来决定。如果两个业务系统之间需要频繁跳转,甚至有路由跳转,那必然是不适合多入口的。多入口之间只能通过直接切换url的方式跳转,这样会让用户体验大打折扣。

vite如何配置多入口

vite官方文档中有关于多页面应用模式如果配置的说明。

按照文档的方式配置完成后,文件目录长下面这样。但是这并不是我理想的文件组织形式,理想的多入口,每个入口的代码文件应当在一个包内,并且多个入口的包应当平级。

image.png

理想多入口改造

接下来按照理想中多入口形式改造文件接口,改造后的文件结构长下面这样。

image.png

改变文件目录后,记得要修改文件之间的引用关系,接下来我们详细看项目配置方面的修改。

首先,我们需要修改打包入口的配置。配置两个入口,分别对应各自的index.html文件所在位置。

// vite.config.ts
...
build: {
    rollupOptions: {
      input: {
        main: path.resolve(__dirname, 'src/packages/mono1/index.html'),
        mono2: path.resolve(__dirname, 'src/packages/mono2/index.html'),
      },
    },
},
...

这样修改完成后,我们分别访问 http://localhost:11000/src/packages/mono1/http://localhost:11000/src/packages/mono2/, 发现是可以访问到各自的index.html文件的,并且能够正常初始化main.ts和App.vue。

但是,如果项目中用了路由就会发现,现在这个方式没有办法正常访问路由。因为我们现在只有使用 /src/packages/mono1 这个路径才能访问到对应的入口,而路由是跟目录或者自定义目录。虽然在路由前加 /src/packages/mono1 就可以访问到了,但我相信没有人会给路由起这样的名字,所以我们需要想别的解决办法。

vite的配置项中,有一个root属性,它指的是项目根目录(index.html文件所在的位置)。可以是一个绝对路径,或者是相对于vite.config.ts配置文件的相对路径。

既然root是index.html所在的问题,那么vite应该会把此路径当做项目根目录加载,也就是路由的根目录。所以理论上我们可以通过修改 root 属性的值来达到正常访问个入口页面路由的目的。下面我们做个试验,修改root属性值如下:

// vite.config.ts

export default defineConfig({
  root: 'src/packages/mono1/',
  // ...
})

现在的root指向了mono1的index.html所在路径,我们重启项目看下效果。

image.png

可以看到,根目录已经可以正常访问路由了。

但是我们执行 npm run build 打包试试。

到现在这是我们第一次执行打包操作,如果你手里的项目是按照系列文章一步步配置过来的,在打包时大概率会遇到一堆 node_modules/element-plus的报错,这是因为打包时 vue-tsc --noEmit 命令对ts进行类型检查报的错。但是node_modules里的内容我们并不需要关心,因此跳过检查即可。在tsconfig.json配置文件的compilerOptions配置项中增加 "skipLibCheck": true,即可跳过对第三方依赖包的检查

操作后会发现打包报错了:

image.png

报错的大概原因是配置root后在打包过程中转化出了相对路径,但是rollup打包并不允许相对路径的存在。具体为什么报错我们这里不用细究,这不是这篇文章要关注的重点。

通过实验我们知道了配置root是一种实现方式,因为我们只需要关系在开发阶段如何不影响开发逻辑的访问不同入口,在打包部署后可以通过代理去匹配不同入口,就不需要纠结这个问题了。

所以有人可能想到在打包发布时注释掉不就可以了吗?但是这样的工作是纯无意义的浪费时间,而且在开发时需要启动到不同的入口,还要每次都修改root参数,这不是我们想要的结果。

本着懒的原则,我们发现vite可以通过vite serve制定根目录,也就说我们可以在启动项目时指定root参数。那这样我们就可以通过配置不同的npm scripts命令来进入不同的入口。 image.png 修改package.json文件如下:

// package.json

"scripts": {
    "mono1": "vite serve src/packages/mono1/ --config ./vite.config.ts",
    "mono2": "vite serve src/packages/mono2/ --config ./vite.config.ts",
}

在这个阶段修改根目录后,启动项目会因为配置文件找不到而报错,所以需要重新手动指定 --config 参数。

修改后,分别运行两个新命令:

image.png

image.png

已经都能正常访问了。

寻求更好的解决方案

在实现这个解决方案前,我也找过其它方案,比如有一个叫 vite-plugin-mpa 的npm工具包,它可以实现启动项目后的自动跳转,但其实做的主要工作就是重定向,而且不能帮助我们解决需要带着文件夹名字访问路由的问题。 除此之外,我还没有找到更完美的解决方案。如果各位大佬有更好的方案,欢迎交流。

代码已上传Git:github.com/YuanDaoDao0…

后记

Vue3 + Vite搭建生产项目的系列文章到这里就算告一段落了,非常感觉能够赏光阅读、点赞我文章的小伙伴们。

由于个人水平有限,并且vue3和vite目前属于较新的东西,网上可供参考的资料甚是有限,并且每个人的观点和方法可能都存在差异。因此文章中难免会有不严谨甚至不正确的地方,并且每个人的开发环境略有差别,可能会导致代码表现差异,如有发现,欢迎大家提出来并多多交流。

最后,码字不易,还望大家多多支持,文明交流。

致谢!