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

p8h8hvxi  于 5个月前  发布在  Webpack
关注(0)|答案(2)|浏览(62)

我有一个vue前端和spring Boot 后端应用程序。我的应用程序有多个具有不同url路径的示例(例如/instance 1,/instance 2),但使用相同的构建项目-这意味着每个示例运行相同的jar。此外,应用程序提供静态文件-编译的vue应用程序的index.html。
我的问题是,vue应用程序需要动态地知道从哪个url路径获取所有静态文件,所以例如,当我获取instance 1的index.html时,它需要从/instance 1/assets获取所有资产
我读了很多关于这个问题的答案,他们都建议像第一个答案一样动态配置webpack_public_path全局变量。
所以在我的vue应用程序中,我这样做了:
main.js文件中:

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

字符串
publicpath.js文件中:

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

上面链接的答案的问题是,它只在我将应用程序作为开发应用程序运行时才对我有效(在vue项目上运行npm run serve时)。在构建项目后,这不起作用,并且构建index.html由spring Boot 提供。

我找不到任何解决这个问题的答案,所以我真的很感激任何帮助
谢谢你,谢谢

vojdkbi0

vojdkbi01#

改变__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.该值作为ENV变量process.env.BASE_URL在代码中可用。
例如Vue-router,当应用程序没有托管在服务器根目录时,也需要一些配置才能正常工作(因为它负责为<router-link>创建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__应该足以解决此问题
1.更大的问题是在构建时生成的index.html中的链接。这些链接显然不受__webpack_public_path__变量的影响。我在这里看到的唯一选择是将生产构建的publicPath设置为某个唯一值,而不是将index.html作为静态文件提供,而是将其作为动态响应-从磁盘阅读文件,将原始publicPath值替换为正确值(针对特定部署)并提供结果

备选方案

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

  1. Vue CLI文档中提示了第二种选择
    值(publicPath)也可以设置为空字符串('')或相对路径(./),以便使用相对路径链接所有资产。这允许将构建的bundle部署在任何公共路径下,或在基于文件系统的环境中使用,如Cordova混合应用程序。
    重点是,如果你的网站使用不带前导斜杠的相对链接,它应该被浏览器解释为相对于当前路径(source)的路径,因此,你可以在任何公共路径下部署。
    决定是你的,因为只有你知道做出决定所需的细节。
inb24sb2

inb24sb22#

如果你使用的是Vue router,你可以在constructor参数中使用base参数来设置自定义路径:

const router = new VueRouter({
  mode: 'history',
  base: `/${window.location.pathname.split('/')[1]}/`,
  routes
})

字符串

相关问题