木灵鱼儿
阅读:1379
vue cli3-cli4 打包后项目在二级路径的方法
默认情况vue的build打包,都是基于根路径来进行的,但是,如果我们将打包的文件放置再二级目录,就会导致文件无法加载,页面空白。
原因有两个:
- 路由路径无法正确匹配
- 资源文件路径错误
下面我们就来讲讲做法
路由配置
在路由实例的创建时,我们常常会看到一个base
选项,内容如下:
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
base官方有很明确是解释:
类型:
string
默认值:"/"
应用的基路径。例如,如果整个单页应用服务在/app/
下,然后base
就应该设为"/app/"
简单的讲就是你的项目文件存放的目录层级,从域名根目录下开始计算。
那么process.env.BASE_URL
是什么意思呢?
process.env是node的一个系统变量,在vue cli中,会对这个process.env做自己的操作,默认情况,再不添加任何自定义环境变量文件的情况下,process.env只有两个属性:
{
"NODE_ENV": "development",
"BASE_URL": "/"
}
不管是在development
还是production
或者其他模式,默认的BASE_URL都是/
;
当然我们可以通过增加自定义环境变量的方式覆盖BASE_URL的属性,也可以通过简单的三元判断达到我们想要的效果。
假设我们的二级目录是:/web
const router = new VueRouter({
mode: 'history',
base: process.env.NODE_ENV === "production" ? "/web" : process.env.BASE_URL,
routes
})
那就设置打包模式下的二级路径为:/web
,开发模式默认值即可。
资源文件路径配置
路由的配置只是让router能正确的识别路径,但是资源文件目前都是这种绝对路径的形式:
<link href="css/app.1920c275.css" rel="preload" as="style">
<script src="js/chunk-vendors.433f29b4.js"></script>
<script src="js/app.fcce27f5.js"></script>
所以,为了文件的加载正确,我们需要配置一下资源的路径地址
在项目根目录打开vue.config.js文件,没有就手动创建,添加以下代码:
module.exports = {
publicPath: "./"
}
publicPath的属性表示在打包输出的资源文件基本路径,它是vue cli基于webpack的output.publicPath
的自定义实现,所以官方不建议直接动output.publicPath
,因为会影响到vue cli其他基于output.publicPath
的设置,所以我们设置publicPath即可。
基本路径可以用router的base属性去理解,一样的意思。
这里我们使用:./
相对路径表示,那么输出的资源文件引用就变成了:
<link href="./css/app.1920c275.css" rel="preload" as="style">
<script src="./js/chunk-vendors.433f29b4.js"></script>
<script src="./js/app.fcce27f5.js"></script>
在html中,./
相对路径表示的是相对于html文件为起点开始的,所以我们可以准确的找到资源文件,只要不改变打包后的html与资源文件的结构。
换个思维,如果我们不想设置./
是否可行?
答案当然是可以的,还是以/web
为例
module.exports = {
publicPath: "/web"
}
<link href="/web/css/app.1920c275.css" rel="preload" as="style">
<script src="/web/js/chunk-vendors.433f29b4.js"></script>
<script src="/web/js/app.fcce27f5.js"></script>
这样也是可以的,只要路径正确就行。
但是这样的话路径就是写死的了,相对来说灵活性就差了一点,如果路径变了,我们除了路由配置要修改,还得改动这个,就比较麻烦,使用相对路径./
,配置一次就不用每次都改动,更加方便
服务器配置
上面两种方法是前端配置,事实上如果真的使用二级目录,且路由模式为history
,那么后端也是需要设置的。
以Nginx为例,默认官方推荐添加以下设置:
location / {
try_files $uri $uri/ /index.html;
}
但是这是相对于根目录的设置,如果是二级目录
location / {
try_files $uri $uri/ /web/index.html;
}
那么也是需要加上/web
的。
放个宝塔的配置图:
更多服务端配置参考官方文档:后端配置例子
最新的理解
vue-router的mode模式会对二级目录的适配有影响,如果你是history
模式,那么即便你在vue.confing.js中设置了publicPath: "./"
,你也无法正确的打开页面,因为你的路由无法识别成功。
publicPath控制的是资源的加载,设置为./
只是让你的js文件,css文件等加载的路径变得正确,并不能让你的路由正确识别。
因为history的路由是/xxx/xxx
的形式,而你的二级目录地址会对这个路径增加一个二级目录路径:
https://xxxx.xxx.com/二级目录/路由名
而你的路由无法正确识别/二级目录/路由名
。
所以你需要配置路由的base为你的二级目录,配置好后,前端相关处理就完成了。
后端的nginx也是要对应处理的,就是为了能在页面刷新后还能正确访问到该页面,具体上面也已经细说了,不做重复赘述。
如果你是hash模式,那么只需要配置publicPath: "./"
就行了,因为二级目录不会影响到路由的识别,哈希模式的路由是哈希参数。
至此,二级目录适配完美。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿 - 有梦就能远航站点。未经许可,禁止转载。
相关推荐
关于给css自动添加浏览器前缀
前言为了兼容之前的旧浏览器版本,特别是安卓4.4这种低版本,transform是一定得增加浏览器前缀的,但是我在项目中遇到了设置无效的问题,极度蛋疼,下面是我的解决教程,当然没这个问题,看这篇文章,相信你对如果给项目增加浏览器前缀,会有很充分的认识。教程给css增加浏览器前缀,业界的做法就是使用postcss,目前webpack与vue cli他们需要安装的依赖略有不同:webpack:pnpm i postcss postcss-loader autoprefixer -D添加对应的rules{ test: /.s?css$/, use: [ ...省略...
vue cli异步路由加载原理
webpack会解析路由文件的引入,就算你是一个setTimeout输出的路由配置文件,或者if else判断的路由配置文件,他都会将你明文书写的路由vue文件打包。为什么?其原理未知,估计并不是解析代码,而且代码关键字的抓取。如果你是一个api返回的路由配置,webpack的无法准确感知到路由文件的是否被引入,所以它的办法是全部都打包,src目录下的所有vue文件全部会被打包成chunk-2d0b30b7.3576daad.js这种格式的文件。其中包裹components目录下的组件,哪怕你的这个组件已经被某个路由页明确引入了,这个路由除了会被打包到这个路由页,还会生成单独的chunk...
关于 vue cli 的Network unavailable的问题分析以及修复方式
发现公司的项目,不管是vue2还是vue3,不管是新创建的还是旧项目,启动后Network永远是unavailable;就很离谱,导致每次想要局域网测试,只能手动在devServer中配置public属性,设置一个固定的本地ip地址。但是,你的ip地址并不是别人的ip地址,那么就会导致如果不小心上传了vue.config.js;那么同事一拉,哦吼,不懂得就说,哎呀,我的项目怎么启动不了了。这就很蛋疼了,所以我分析了一下这个问题的原因。首先,我的电脑的环境是没有问题的,网卡也是没有问题的,vue cli早就支持多个网卡了,所以多网卡问题就可以忽略。其实主要原因是因为一个不合法的ipv4地址...

webpack5 externals打包时取消打包指定的库
简单说明externals这个属性,常用来做cdn的功能,在打包的时候不打包指定的库,比如vue,jquery,然后在html文件部分,手动引入库的cdn链接,但是,你在开发的时候,你还是需要npm或者yarn安装这个库,import引入使用,只是打包的时候会自动剔除。简单示例webpack.config.jsmodule.exports = { externals: { uikit: "UIkit", } }可以看到,externals是一个对象,对象里面有key和value,其中key的值就是package.json里面,安装的包的名字。而valu...

vue cli4 修改静态html的 %= htmlWebpackPlugin.options.title % 默认值
在默认初始化好的vue cli项目,public目录下的index.html文件,他的title使用的是一种ejs语法:<title><%= htmlWebpackPlugin.options.title %></title>接收的是htmlWebpackPlugin对象上,options的title。一般情况,省事一点,直接把这个title给改成静态就完事了!<title>静态标题</title>但是,好像少了点什么,能不能不改动这个就能改标题呢?当然是可以的,我们需要配置下vue.config.jsvue.config.js...
vue cli4 全局scss变量技巧
今天啃了下官方文档,加上之前也配置到webpack的,有一些经验,我觉得官方可能有对应的方式,毕竟在webpack中我们只需要在sass-loader配置中就可以加入全局scss了,都不用安装啥插件。于是乎,果然,官方有,但是文档很蛋疼,你能看懂引入单个全局,没有多个全局的示例,索性自己写个笔记了。vue.config.jsmodule.exports = { css: { loaderOptions: { scss: { prependData: ` @import "~@/base/assets/scss/glob...
关于vue cli打包提示 chunk chunk-ec595700 [mini-css-extract-plugin] css的顺序和冲突警告的问题
莫名其妙就提示css冲突和顺序问题,而且组件里面的样式和class类名完全不相干,不知道怎么就给你冲突了。顺序都有点莫名其妙,这玩意谁先谁后都无所谓啊。看了好半天github上的issues也没有谁说出个所以然,反正就是大量的警告,18年就有人提出这个问题了,唉,头疼issues目前普遍的解决办法就是忽略这个警告,因为不是真的影响代码的运行。忽略警告打开vue.config.js文件夹,插入以下代码:module.exports = { css: { extract: { ignoreOrder: true }, }, }保存,然后重新打包,不会再提示 冲突和顺序问题了
![关于vue cli打包提示 chunk chunk-ec595700 [mini-css-extract-plugin] css的顺序和冲突警告的问题](https://mulingyuer-1253375624.cos.ap-guangzhou.myqcloud.com/%E5%9B%BE%E7%89%87%E7%A9%BA%E9%97%B4/%E5%85%B3%E4%BA%8Evue%20cli%E6%89%93%E5%8C%85%E6%8F%90%E7%A4%BA%20chunk%20chunk-ec595700%20%5Bmini-css-extract-plugin%5D%20css%E7%9A%84%E9%A1%BA%E5%BA%8F%E5%92%8C%E5%86%B2%E7%AA%81%E8%AD%A6%E5%91%8A%E7%9A%84%E9%97%AE%E9%A2%9801.jpg!Anti_theft)
vue cli4 打包时自动去除所有console以及白名单
经常漏删console真的很头疼,又不得不重新打包,所以希望有一款能在打包时自动删除console的插件。于是乎,就有了这篇文章。安装yarn add babel-plugin-transform-remove-console --dev安装完毕我们开始使用使用打开_babel.config.js_文件,输入以下代码,没有这个文件就手动创建。let plugins = []; if (process.env.NODE_ENV === 'production') { //正式环境自动删除console plugins.push('transform-remove-console')...
vue cli 指定打包输出的路径
因为有这个需求,所以分享出来,省的百度找到的都是一堆垃圾文章。vue.config.js配置一个属性即可module.exports = { //指定输出路径 outputDir: 'build/dist' }outputDir配置输出的路径,默认是dist,我打包后文件输出到当前目录(vue.config.js相对)下的build目录下的dist文件夹
vue 路由跳转使用新建页面打开
今天遇到这么一个需求,官网的个别页面需要新建页面打开,但是这个页面我是配置的路由。一直以来,我以为路由的跳转只能就是在当前页面进行,特别是我跳转路由使用的都是路由name属性。接到这个请求我有点懵逼了,哈哈。。解决方法router-link元素默认生成的是一个a元素,仔细查看你会发现a元素的href是带有路径链接的,哪怕你跳转的:to="{name:xxx}"使用的是路由name。它最终生成的a元素,href依旧是路由的path,所以,既然他能生成路径,那么我们只需要给他加上a元素的attr属性target即可。<router-link :to="{n...