关于前端:关于Vue项目中publicPath的二三事

33次阅读

共计 3972 个字符,预计需要花费 10 分钟才能阅读完成。

引言

Vue 我的项目中,vue.config.js 是我的项目中用来做启动和打包的配置文件,其中有一个重要参数是 publicPath,这个配置的作用是在开发阶段和生产阶段,为动态资源配置对立的资源标识符。
然而,有的时候,相对路径、绝对路径、二级门路傻傻分不清。再不然就是开发阶段利用跑的好好的,而一但到了生产环境,不是白屏就是图片资源丢了,总之就是各种问题。明天就来好好的 battle 一下,到底在各种各样的场景下,这个参数应该怎么配。


相对和绝对之分

在讲配置前,首先来明确两个概念绝对路径 ‘/’ 和 相对路径 ‘./’。这两个概念的区别就是以哪个目录作为终点,能够了解为绝对路径就是相对错不了的门路,始终以一个固定的目录作为终点。而相对路径容易错,能够是任意一个目录节点作为终点。而在网站的拜访中,能够认为如果动态资源应用了绝对路径,那么他始终以以后这个网站来作为拜访的根节点。

在 vue.config.js 中,publicPath 既可配置成绝对路径,也能够配置成相对路径。

  • 绝对路径:

    publicPath: '/',
    // 或带有二级门路的网站, 如拜访地址为 http://my-app.com/sub/
    publicPath: '/sub/'
  • 相对路径:

    publicPath: './',
    // 或者
    publicPath: '.',
    // 或者
    publicPath: ''

    以上三种是等效的,都是相对路径。


对于 publicPath

首先应用 @vue/cli 的脚手架,生成一个 vue 我的项目,来看一下 publicPath 的默认配置是什么?
以下代码均来自 @vue/cli@5.0.8。

生成的 vue.config.js

能够看到在生成的我的项目中,publicPath 的参数值并不存在,那么这个默认值到底是什么呢?关上 @vue/cli 的源码 在 packages/@vue/cli-service/lib/options.js 文件下找到了答案。

能够看到脚手架默认赋予的 publicPath 的值为 ‘/’,也就是说 @vue/cli 默认应用的是绝对路径。


对于 router 中的 base 参数

除了 publicPath 这个参数外,还有一个与之有严密关系的参数就是 router 当中的 base。

关上 vue-router 的官网文档能够看到对应的解释,base 是利用的基门路,即以后利用的所有的路由地址,都会被主动拼接上这个基门路,个别利用在部署有二级目录的网站上。

router/index.js 中 base 的 默认值为 process.env.BASE_URL,那么这个初始值是什么呢?持续翻找 @vue/cli 的源码,在以下文件中找到了答案

目录:packages/@vue/cli-service/lib/config/base.js
此文件是 @vue/cli 对 webpack 的配置文件,能够看到脚手架中的环境变量来自于 util/resolveClientEnv 这个工具函数,而后调用 webpack.DefinePlugin 的插件,将这些环境变量生成最终可拜访的常量。

目录:packages/@vue/cli-service/lib/util/resolveClientEnv.js
此文件是 @vue/cli 用来生成环境变量的工具函数,能够看到 BASE_URL 的 值来自 getBaseUrl 这个函数,而参数 options 就是咱们的 vue.config.js 所导出的 json 文件。此外还能够看到在脚手架中默认只有 VUE_APP_结尾、NODE_ENV、BASE_URL 这三种环境变量才能够被 @vue/cli 所辨认。

目录:packages/@vue/cli-service/lib/util/.js
能够看到当 publicPath 被设置为 ‘auto’ 后其值是 ”,而其余状况下,这个值就是咱们所配置的 publicPath,那根本能够了解为,publicPath 和 router 中的 base 参数,在理论我的项目的开发中理当是同一个值。

而这里独自解决 ‘auto’,是为了适配 webpack,因为 webpack 的 output.publicPath 能够设置为 ‘auto’ 并有其本人的解决逻辑。但一旦应用了 ‘auto’ 这个值,在启动 serve 后,auto 就会被当成二级门路比方 http://localhost:8080/auto/,所以 @vue/cli 要在这里强制将其置空。

这个问题的探讨地址:[https://github.com/vuejs/vue-…]
(https://github.com/vuejs/vue-…)
webpack 对于 publicPath 的文档:https://webpack.docschina.org/configuration/output/#outputpublicpath

好了,看明确了默认值当前,终于能够开始进入正题了,publicPath 别离在相对和相对路径下应该怎么用。


publicPath: ‘/’,应用绝对路径,即默认配置

开发环境

生产环境

论断: 应用默认配置,无论是在开发阶段还是生产阶段,动态资源都会被挂上 ‘/’,这样动态资源就会以以后网站服务作为根节点,而后加载相应的动态资源。

本地动态拜访

而这样打进去的 dist/index.html 也是无奈间接拜访的,因为应用了绝对路径,当间接应用浏览器关上时,会间接去到根目录的盘符下作为拜访的根门路,导致动态资源加载失败。当然生产包打进去个别都会应用服务器进行部署,因为大多数利用还有和后盾接口的交互,必须要通过服务器启动后能力失常拜访。
那么有没有不必服务器就能启动进行拜访的么?这时候你可能须要的就是相对路径。


publicPath: ‘./’,应用相对路径

开发环境

生产环境

论断: 应用相对路径,能够看到只是比绝对路径在动态资源拜访上少了 ‘/’,这样的长处就是能够让以后利用被部署在任意目录,而不用放心动态资源有失落的状况。比方本地拜访。

能够看到应用相对路径进行打包后,间接本地拜访 index.html,动态资源都是加载胜利的,页面上显示了一部分货色,然而 home 页面的内容却失落了。这其实是因为咱们应用的路由模式是 history,尽管资源加载没有问题,然而因为地址栏门路与前端设置的拜访路由不统一,导致前端路由不能正确加载,因而页面不能正确显示。

把路由批改为 hash 模式。

能够看到,当批改了路由为 hash 模式后,再次进行打包,index.html 即使在本地也能够顺利的进行拜访了,进行路由切换也毫无问题。


publicPath: ‘/sub/’,采纳二级门路 (也是绝对路径)

开发环境

生产环境

论断: 能够看到,二级门路其实也是绝对路径,只不过在所有动态资源前对立拼接上了 ‘/sub/’。这种配置能够在同一个域下部署不同的我的项目,依附二级门路来做到逻辑上的划分。


为什么当网站配置了二级拜访门路,前端也要加上相应资源标识符呢?

当应用绝对路径时,所谓根门路,其实是以以后 域名 + 端口号前面的地位开始的。如以 http://localhost:8080/test 这个网址为例,如果此时前端配置的 publicPath: ‘/’,即默认值。那么打进去的前端动态资源在被加载时,就会变成 http://localhost:8080/js/xxxx…,因为端口后才是以后网站的根目录。如此一来,动态资源在物理层面曾经无奈被拜访到了,导致资源加载失败,页面白屏等。
所以当网站设置了二级目录时,前端这时候就须要留神了,能够有不同的解决方案避免白屏。

  1. 设置带有二级目录的绝对路径,publicPath: ‘/test/’,这样打包进去的动态资源能够和以后网站的配置保持一致,能够防止资源加载失败。
  2. 设置相对路径,publicPath: ‘./’。然而这样一来,如果此时应用的是 history 模式的路由配置,因为网站加了二级目录会导致前端的路由地址匹配失败,所以还须要将 router 的 base 设置为 ‘/test/’ 须要与网站的二级目录保持一致。或者间接采纳 hash 的路由模式,这样能够疏忽掉 base 参数的配置,比拟省心。

对于 vue-cli 的官网文档对 publicPath 字段的解释

这个值在开发环境下同样失效。如果你想把开发服务器架设在根门路,你能够应用一个条件式的值:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/production-sub-path/'
    : '/'
}

官网文档说的很分明,总结以下几种配置模式不便记忆:

  1. 傻瓜模式:路由采纳 hash 模式,publicPath 采纳相对路径 ‘./’ 模式,此种组合配置操作简略,能够部署到任意门路上,并且能反对二级目录,比拟省心。即使是间接拜访打包后的 index.html 也能看到成果,利用的场景可能如下:

    • 一个纯前端利用,不须要和后盾的接口进行交互,反对本地动态展现。
    • 只是用来部署到 github gh-page 分支下的纯前端展现利用。
    • 如应用 vue 开发的 h5 我的项目,而后应用 hbuilder 进行打包的 hybird app。
    • 部署在带有二级门路的网站上。
  2. 进阶模式:路由采纳 history 模式,publicPath 采纳绝对路径 ‘/’ 模式,此这种模式须要服务器来对前端资源进行部署。同时,还须要在服务器上配置 404 重定向到 index.html。
  3. 降级模式:路由采纳 history 模式,publicPath 采纳了 ‘/sub/’ 二级门路,相应的 router base 参数也应该设置为 ‘/sub/’ (通常应用脚手架默认提供的 process.env.BASE_URL 即可)。此种模式即在多个我的项目同时部署到一个域名和端口下时,采纳不同的二级门路来对我的项目进行逻辑上的划分。与进阶模式的服务部署形式雷同。

正文完
 0