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

Noy*_*fni 6 webpack vue.js vue-cli

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

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

我读了这个问题的许多答案,他们基本上都建议动态配置webpack_public_path全局变量,就像第一个答案一样

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

main.js文件中:

import './publicpath'
import Vue from 'vue'
Run Code Online (Sandbox Code Playgroud)

然后在publicpath.js文件中:

__webpack_public_path__ = `/${window.location.pathname.split('/')[1]}/`
Run Code Online (Sandbox Code Playgroud)

上面链接的答案的问题是,它仅适用于我将应用程序作为开发应用程序运行时(在npm run servevue 项目上运行时)。构建项目后这不起作用,构建的index.html由spring boot提供。

我找不到任何解决这个问题的答案,所以我非常感谢任何帮助

谢谢你!

Mic*_*evý 13

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

为什么

Vue CLI 有一个publicPath选项:

默认情况下,Vue CLI 假设您的应用程序将部署在域的根目录下,例如https://www.my-app.com/. 如果您的应用程序部署在子路径中,则需要使用此选项指定该子路径。例如,如果您的应用程序部署在https://www.foobar.com/my-app/,则设置publicPath'/my-app/'

该值在多个地方使用:

  1. 要配置 Webpack - 设置它的output.publicPath 选项

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

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

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

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

例如,当应用程序未托管在服务器根目录中时,Vue-router 还需要一些配置才能正常工作(因为它负责创建 URL <router-link>)。大多数时候,这是在配置中使用这一行来完成的:base: process.env.BASE_URL

或者您可能需要配置 Axios 的基本 url 来进行 API 调用...

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

如何

__webpack_public_path__从以上所有内容中可以清楚地看出,仅按照链接答案的建议替换运行时的值是不够的。那么还需要什么呢?

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

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

备择方案

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

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

值 ( publicPath) 还可以设置为空字符串 ( '') 或相对路径 ( ./),以便使用相对路径链接所有资源。这允许将构建的包部署在任何公共路径下,或在基于文件系统的环境(如 Cordova 混合应用程序)中使用。

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

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