在 vue 应用程序中构建后动态设置 __webpack_public_path__ 不起作用

dynamically setting __webpack_public_path__ does not work after build in vue application

我有一个 vue 前端,spring 引导后端应用程序。 我的应用程序有多个具有不同 url 路径的实例(例如 /instance1、/instance2),但使用相同的构建项目——这意味着每个实例 运行 都是同一个 jar。 该应用程序还提供静态文件 - 已编译的 vue 应用程序的 index.html。

我的问题是 vue 应用程序需要动态地知道从哪个 url 路径获取它的所有静态文件,所以例如当我获取 instance1 的 index.html 它需要获取所有来自 /instance1/assets

的资产

我读了很多关于这个问题的答案,他们基本上都建议动态配置 webpack_public_path 全局变量,如 this first answer

所以在我的 vue 应用程序中我这样做了:

main.js 文件中:

import './publicpath'
import Vue from 'vue'

然后在 publicpath.js 文件中:

__webpack_public_path__ = `/${window.location.pathname.split('/')[1]}/`

问题 上面链接的答案是,它只适用于我 运行 作为开发应用程序的应用程序(当 运行ning npm run serve 在 vue 项目上)。这在 构建 项目后不起作用,构建 index.html 由 spring 引导服务。

我找不到任何解决此问题的答案,因此非常感谢任何帮助

谢谢!

改变 __webpack_public_path__ 可能还不够....

为什么

Vue CLI 有一个 publicPath 选项:

By default, Vue CLI assumes your app will be deployed at the root of a domain, e.g. https://www.my-app.com/. If your app is deployed at a sub-path, you will need to specify that sub-path using this option. For example, if your app is deployed at https://www.foobar.com/my-app/, set publicPath to '/my-app/'

这个值在多个地方使用:

  1. 要配置 Webpack - 将其设置为 output.publicPath option

该值在构建时和运行时都很重要。

在运行时,它作为全局 JS 变量 __webpack_public_path__ 可用,并在为任何模块请求(加载动态 JS 块、引用图像等)创建 URL 时使用(由 Webpack)。 )

在构建时,它也用于创建 URL,但这次用于将您的应用程序加载到浏览器中所需的资产 - 所有 <link><script> 标签负责加载您应用的所有 JavaScript 和 CSS。这些被直接注入 index.html 作为 硬编码字符串

  1. 该值作为 ENV 变量可用 process.env.BASE_URL,可在您的代码中使用。这个变量很有用

例如 Vue-router,当应用程序未托管在服务器根目录中时,requires some configuration 也能正常工作(因为它负责为 <router-link> 创建 URL)。这是大部分时间在其配置中使用此行完成的:base: process.env.BASE_URL

或者您可能需要为 Axios 配置基础 url 以进行 API 调用...

所有这一切都归功于 Webpack 的 DefinePlugin。真正重要的是要了解它是如何工作的。任何时候你在代码中使用 process.env.BASE_URL,Webpack 都会在构建时 期间用配置的值替换该字符串 (即在运行时没有变量 process.env.BASE_URL 知道)

如何

综上所述,现在应该很清楚,仅按照 linked answer 的建议在运行时替换 __webpack_public_path__ 的值是不够的。那么还需要什么?

  1. 不要在代码中的任何地方使用 process.env.BASE_URL。使用 __webpack_public_path__ 应该足以解决这个问题

  2. 更大的问题是 index.html 中的 link 是在构建期间生成的。这些显然不受 __webpack_public_path__ 变量的影响。我在这里看到的唯一选项是将生产构建的 publicPath 设置为某个唯一值,而不是将 index.html 作为静态文件提供,而是将其作为动态响应提供 - 从磁盘读取文件,替换原始 publicPath 具有正确值(针对特定部署)并提供结果的值

备选方案

  1. 第一个明显的替代方法是设置多个 CI/CD 管道,使用 ENV 变量为每个管道配置 publicPath 并为每个实例构建单独的包

  2. Vue CLI 中暗示了第二种选择 documentation

The value (publicPath) can also be set to an empty string ('') or a relative path (./) so that all assets are linked using relative paths. This allows the built bundle to be deployed under any public path, or used in a file system based environment like a Cordova hybrid app.

重点是,如果您的站点使用不带前导斜杠的相对 link,浏览器应将其解释为相对于当前路径 (source) 的路径,因此,您可以在任何 public 路径下部署...

决定权在您,因为只有您知道制作一个所需的细节...