终于明白publicPath和base配置,念头通达了
前言
这里说的publicPath是webpack中output对象的一个属性,base是vue-router的路由前缀。
网络请求中的路径
理解publicPath和base之前,我们需要明确网络请求中路径的概念。在网络请求中路径分为相对路径和绝对路径,但不管是相对路径还是绝对路径,最后都要生成一个完整的url。
绝对路径
绝对路径和path没有关系,拿这个网址举例 https://xxx.hrsass.com/gd/hrsaas/sso/login
,大家都知道它本身就是一个绝对路径。和path没有关系也就意味着只关心https://xxx.hrsass.com
,而不关注后面是什么东西。
- 省略域名
/gd/hrsaas/sso/login
,这种写法其实也是一种绝对路径,它会自动拼接上当前页面的域名。
例如我当前页面是www.baidu.com/xxxx 在当前网页下执行window.location.href = '/gd/hrsaas/sso/login'
,会跳转到 www.baidu.com/gd/hrsaas/s…
- 省略协议名
//xxx.hrsass.com/gd/hrsaas/sso/login
,这种写法访问时会自动拼接上当前网页的协议名。
相对路径
./static/index.css
相对路径相对的是当前url的path部分,例如路径是https://xxx.hrsass.com/gd/hrsaas/sso/login
,在当前网页下执行window.location.href = './static/index.css'
,会跳转到https://xxx.hrsass.com/gd/hrsaas/sso/static/index.css
。 ./static/index.css
等同于 static/index.css
。
同理 window.location.href =../static/index.css
会跳转到https://xxx.hrsass.com/gd/hrsaas/static/index.css
。
publicPath的作用
这个配置主要是作用在生产环境下,如果发现本地代码跑的好好的,放到生产上资源都加载不到很可能就是因为这个配置的原因。在webpack和vite都有这个配置,只是配置的地方和属性名不同。它的主要作用是为我们打包后的内容添加前缀。
publicPath的配置如下
output: {
filename: '[name].js',
publicPath: '/gd/hrsass/sso',
},
执行npm run build
后dist打包结果如下,index.html中引入的链接自动添加上了这个前缀。这就是publicPath配置的作用。
打包的内容为什么要添加这个前缀呢?这是因为在真正的企业项目中,往往会把多个项目部署在一个域名下。就我们公司而言https://xxx.hrsass.com/gd/hrsaas/sso/xxx
是工作台的项目,https://xxx.hrsass.com/gd/hrsaas/xst/xxx
是人事薪税的项目等。这些不同的项目是一个域名https://xxx.hrsass.com
,根据不同的路径来访问不同的静态资源。/gd/hrsaas/sso
对应的就是工作台,/gd/hrsaas/xst
对应的就是人事,这是凭借nginx
实现的。下面是nginx
的配置
这也就是我们为什么要设置publicPath,就是为了让index.html中引入的css,js发出的请求(link,script下载资源本身就是get请求),能被nginx匹配到从而拿到对应的静态资源。
我现在是在首页url:https://xxx.hrsass.com/gd/hrsaas/sso
,由于我配置的publicPath为/gd/hrsass/sso是绝对路径基于域名发送请求,打包后的srcipt文件src=“/gd/hrsass/sso/static/js/app.638e6c6d.js”,所以它请求的路径就是https://xxx.hrsass.com/gd/hrsass/sso/static/js/app.638e6c6d.js
,从而能成功匹配到nginx拿到资源。
如果我没配置publicPath,相当于publicPath='',打包后的结果为
同样是在https://xxx.hrsass.com/gd/hrsaas/sso/
,由于href='static/js/app.c364d145.js ' 等同于href='./static/js/app.c364d145.js ' ,它是个相对路径基于path。请求的资源完整的url为 https://xxx.hrsass.com/gd/hrsaas/static/js/app.c364d145.js
。与nginx配置不匹配也就自然而然的拿不到资源。
base的作用
这里说的base是指vue-router的配置,它的作用是为路由添加前缀。例如路由配置的路径是/home
,访问地址为:http://localhost:8080/home ,base设置为'/gd/hrsass/sso',访问的路径就变成了http://localhost:8080/gd/hrsass/sso/home。
let router = new Router({
mode: 'history',
base: window.env.staticPath,
routes:[]
})
为什么要配置base呢,当我们publicPath配置正确后,可以拿到js的资源,页面的加载就由vue-router控制了。如果不配置base,router配置的路由为https://xxx.hrsass.com/home
,上面提到了这个url是拿不到资源的,因为不满足nginx的配置。https://xxx.hrsass.com/gd/hrsass/sso/home
,能拿到资源但是又不满足路由配置。所以base也要配置为/gd/hrsass/sso
,页面才能正常的呈现出来。
结尾
前端开发通常都是写写页面,调调接口啥的,导致我对于配置部署这方面的知识一直是很模糊。直到前阵子公司要采用微前端,其中需要配置基座的前缀与子应用的路由base属性对应,才被迫了解了这块的知识,写这篇文章记录下,希望大家也能有所收获!
转载自:https://juejin.cn/post/7352091152583409675