在 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/'
这个值在多个地方使用:
- 要配置 Webpack - 将其设置为 output.publicPath option。
该值在构建时和运行时都很重要。
在运行时,它作为全局 JS 变量 __webpack_public_path__
可用,并在为任何模块请求(加载动态 JS 块、引用图像等)创建 URL 时使用(由 Webpack)。 )
在构建时,它也用于创建 URL,但这次用于将您的应用程序加载到浏览器中所需的资产 - 所有 <link>
和 <script>
标签负责加载您应用的所有 JavaScript 和 CSS。这些被直接注入 index.html
作为 硬编码字符串
- 该值作为 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__
的值是不够的。那么还需要什么?
不要在代码中的任何地方使用 process.env.BASE_URL
。使用 __webpack_public_path__
应该足以解决这个问题
更大的问题是 index.html
中的 link 是在构建期间生成的。这些显然不受 __webpack_public_path__
变量的影响。我在这里看到的唯一选项是将生产构建的 publicPath
设置为某个唯一值,而不是将 index.html
作为静态文件提供,而是将其作为动态响应提供 - 从磁盘读取文件,替换原始 publicPath
具有正确值(针对特定部署)并提供结果的值
备选方案
第一个明显的替代方法是设置多个 CI/CD 管道,使用 ENV 变量为每个管道配置 publicPath
并为每个实例构建单独的包
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 路径下部署...
决定权在您,因为只有您知道制作一个所需的细节...
我有一个 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 athttps://www.foobar.com/my-app/
, setpublicPath
to'/my-app/'
这个值在多个地方使用:
- 要配置 Webpack - 将其设置为 output.publicPath option。
该值在构建时和运行时都很重要。
在运行时,它作为全局 JS 变量 __webpack_public_path__
可用,并在为任何模块请求(加载动态 JS 块、引用图像等)创建 URL 时使用(由 Webpack)。 )
在构建时,它也用于创建 URL,但这次用于将您的应用程序加载到浏览器中所需的资产 - 所有 <link>
和 <script>
标签负责加载您应用的所有 JavaScript 和 CSS。这些被直接注入 index.html
作为 硬编码字符串
- 该值作为 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__
的值是不够的。那么还需要什么?
不要在代码中的任何地方使用
process.env.BASE_URL
。使用__webpack_public_path__
应该足以解决这个问题更大的问题是
index.html
中的 link 是在构建期间生成的。这些显然不受__webpack_public_path__
变量的影响。我在这里看到的唯一选项是将生产构建的publicPath
设置为某个唯一值,而不是将index.html
作为静态文件提供,而是将其作为动态响应提供 - 从磁盘读取文件,替换原始publicPath
具有正确值(针对特定部署)并提供结果的值
备选方案
第一个明显的替代方法是设置多个 CI/CD 管道,使用 ENV 变量为每个管道配置
publicPath
并为每个实例构建单独的包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 路径下部署...
决定权在您,因为只有您知道制作一个所需的细节...