Vue2应用给app.js加查询参数去缓存时chunk与静态资源加载异常
问题根因
你遇到的路径拼接错误本质是webpack运行时计算公共路径时未剥离入口JS的查询参数导致的:webpack默认会取当前执行的入口脚本的URL,移除文件名后作为公共路径拼接后续资源,但是不会自动处理末尾的查询参数,所以才会把?v=xxx直接拼到资源名前面。
解决方案1:微应用内自动修正公共路径(无需修改主应用)
无需调整主应用代码,仅修改微应用配置即可适配任意查询参数后缀:
- 在Vue2微应用中新增
src/set-public-path.js文件,内容如下:
// 该文件必须在所有业务代码/资源导入前执行 const currentScript = document.currentScript if (currentScript) { // 剥离查询参数,提取当前app.js所在的目录作为公共路径 const scriptFullPath = currentScript.src.split('?')[0] const appPublicPath = scriptFullPath.substring(0, scriptFullPath.lastIndexOf('/') + 1) // 覆盖webpack默认的公共路径 __webpack_public_path__ = appPublicPath }
- 在
src/main.js的第一行引入该文件:
import './set-public-path' // 后续其他import和业务逻辑保持不变
该方案兼容所有现代浏览器,不管你给app.js加时间戳、版本号还是哈希后缀都能自动适配。
解决方案2:主应用传参指定公共路径(兼容性更强)
如果需要兼容不支持document.currentScript的老旧浏览器,可以选择主应用传参的方案:
- 主应用注册微应用时,传入对应微应用的静态资源基础路径:
import { registerApplication } from 'single-spa' registerApplication({ name: 'app-one', app: () => import('http://localhost:5000/app-one/app.js?v=324324'), activeWhen: ['/app-one'], customProps: { // 直接指定该微应用的资源根路径 publicPath: 'http://localhost:5000/app-one/' } })
- 微应用的
main.js中,在bootstrap生命周期里设置公共路径:
import Vue from 'vue' import App from './App.vue' import router from './router' let vueInstance = null export async function bootstrap(props) { // 用主应用传入的路径覆盖webpack公共路径 __webpack_public_path__ = props.publicPath } export async function mount(props) { vueInstance = new Vue({ router, render: h => h(App) }).$mount(props.container) } // unmount等其他生命周期逻辑保持不变
补充说明
两种方案都不需要修改现有构建配置、不需要调整S3文件结构,完全满足你保留app.js固定文件名、无需重构建主应用的需求。如果使用Vue CLI构建,只要保证vue.config.js中的publicPath不写死绝对路径,保持默认的''或者'auto'即可。
内容的提问来源于stack exchange,提问作者Christian Benseler
相关产品推荐
相关产品推荐

