一个域名部署多个vue项目的方法
前言
在生产环境中,一般一个域名对应一个前端项目,但如果域名紧张,不想浪费二级域名,或者自己的测试项目,完全可以一个域名对应多个前端项目、
以 vue 为例,要实现这一点,需要 vue-router 中的 base 选项助力
2. base 简介
base 选项设置应用的基路径。例如,如果整个单页应用服务在 /app/
下,然后 base
就应该设为 "/app/"
base 选项的默认值为 “/”,这个代表什么意思呢?
我们知道,无论是开发模式下,还是生产模式下,我们都需要启动一个服务来运行我们的前端项目,如
- 开发模式下,可能是 http://127.0.0.1:8080
- 生产环境下,可能是 http://www.xxxx.com
这两个服务都映射到了前端项目的根目录,比如此时路由规则中有这么几个规则
const routes = [
{ path: '/hot', name: 'hot', component: Hot },
{ path: '/local', name: 'local', component: Local },
{ path: '/money', name: 'money', component: Money },
{ path: '/detail/:id', name: 'detail', component: Detail },
]
此时,base 选项的值设置为 “/”
那么在地址栏中的路径就是这样的
http://localhost:8080/hot
http://localhost:8080/local
http://localhost:8080/money
http://localhost:8080/detail/5
也就是域名(http://127.0.0.1也可以看作本地开发的域名)后面直接匹配 hash 值(路由规则中的 path 值),即可
3. base 设置其他值
如果此时设置 base 为其他值呢?
那么地址栏就会变成这个样子,程序仍然能够正常运行
看起来,这个属性就是在域名后面加上了一个虚拟路径,并没什么用,其实不然!
4. 一个域名对应多个项目
抛开开发环境,在生产环境中,如果一个域名想要对应两个 SPA 应用,我们该如何解决呢?
比如,我们有两个项目,分别执行 build 打包后,生成 dist 目录,一个改名为 toutiao,一个改名为 douyin,然后将这两个目录拷贝到某个目录下(我这里是 unittest)
因为一个域名要对应两个 SPA 项目,所以我们的域名肯定是要映射到 unittset 目录,而不是 toutiao 或者 douyin 目录
我们这里使用 http-server 开启一个服务模拟即可,不用真的放到服务器上,使用域名进行映射,因为道理都是一样的
在 unittest 目录下,打开 powshell,然后通过 http-server 启动服务,此时下面的域名都映射到了 unittest 目录
此时,地址栏中输入http://localhost:8080/toutiao
,会报错,如果是访问http://localhost:8080/toutiao/host
页面还会直接报404错误,
通过上图分析得知
- 访问
http://localhost:8080/toutiao
时,其实访问的是 toutiao 目录下的 index.html - index.html 作为 SPA 应用中唯一的html,其内部引用了打包后的 js 和 css 文件
- 但是这些文件的路径是不对的,如
http://localhost:8080/js/chunk-vendors.b57b554e.js
,因为地址http://localhost:8080/
映射的是 unittest 目录,所以 js 文件的实际路径应该在地址后面加上 toutiao,也就是http://localhost:8080/toutiao/js/chunk-vendors.b57b554e.js
,但是很明显这里没有加上
4.通过 base 解决问题
通过设置 base 选项,可以解决上面问题
首先,创建路由对象时,加上base 选项
另外一个项目,也进行配置
但是,光这样是不行的,这样只能保证,在地址栏后面自动加入 toutiao 或则 douyin 这种路径,但是 index.html 中引入的 js 等资源文件还是与原来一样,如何在打包的时候,自动为资源引用地址中加入 toutiao 或者 douyin 这些路径呢?这就需要进行 webpack 配置。在vue.config.js 中,加入如下配置
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
// 配置打包时资源引用的的前置路径
publicPath: process.env.NODE_ENV === 'production'
? '/toutiao/'
: '/'
})
此时,我们再重新打包 npm run build
,再次将打包后的 dist 目录改名为 toutiao 或者 douyin 拷贝到 unittest 目录下,然后地址栏中输入跟上面一样的地址
我们发现,对于 js 等资源文件的引用,路径就对了
总结:路由中的 base 选项与 publicPath 选项配合,就可以做到部署项目时,一个域名映射多个前端 SPA 项目