解决阿里qiankun微应用资源无法加载

解决阿里qiankun微应用资源无法加载

公司老项目多了,却想用新版本的框架,最好的解决办法就是用微前端。 本文说下我们在用阿里微前端框架qiankun,遇到的一些问题,以及一些巧妙的解决办法。

背景

因为接入微前端很长时间了,导致现在的微应用变成了实际意义上的主应用,主应用反而没有多少功能。于是,想着能不能把两个项目的角色换一下,老的主应用项目,变成微应用;微应用项目变成主应用。这样做有两个好处:

如果当前需求不涉及老业务,微应用的老代码就不用发版了。可以顺便升级项目的路由、鉴权等基础逻辑。

于是,开整。

遇到问题

很快,升级工作进行的差不多了,提测的过程中,发现有些资源文件无法加载,如下图:

于是快速定位,发现是老代码变成微应用之后,在加载资源时,路径还是走主应用。比如:

主应用: http: //my.proj.com/main-proj/static/select.png微应用: http: //my.proj.com/micro-proj/static/select.png

本来应该是下面的路径才对,却显示成上面的路径,所以找不到资源。

官方答疑

其实这个问题很多人有遇到 ,于是去官方看下有没有解决方案: 一看还真有,在官方常见问题中有提到:

添加publicPath 、调整静态资源的地址和转Base64.

尝试解决

首先,我们真实环境,老项目是用vue1.x是5年前的项目,我看了下,vue-router还是0.7.x的版本,那个时候,路由配置还没有base,也就是官方教程里的配置:

vue-router0.7.x版本源码:

即使你按照官方的配置走了,也是不起作用的,因为早期版本不支持。找不到base相关的代码。

那为什么不升级老项目呢?

这个问题我也想过,只是项目太复杂且工作量太大,我情愿找到一个能解决资源路径的办法也不想去动老代码。

继续想办法

如果启动的时候配置不了base,那打包的时候行吗?答案是可以,但是有问题。我尝试在webpack中添加publicpath。

module.exports = function (config) {

const webpack = require(path.resolve(config.mumbleDir, './node_modules/webpack'));

const cfg = {

......

module: {

noParse: [/vue-router\.js/]

},

devServer: {

headers: {

'Access-Control-Allow-Origin': '*'

}

},

output: {

filename: '[name].js', // 输出文件名

library: `${name}-[name]`, // 暴露给全局变量的名称

libraryTarget: 'umd', // 导出库方式

umdNamedDefine: true, // 是否将AMD模块命名

publicPath: `${

config.env === 'develop'

? 'http://my.proj.com/micro-proj'

: 'http://my.prod.proj.com/micro-proj'

}/static/`

}

};

return cfg;

};

通过这样的配置,可以部分资源能够使用,为啥说部分资源呢?因为老的webpack在打包静态资源的时候有些资源在Css文件中的路径是相对路径。

往后讲,我们也有CDN资源,但是这个只用于对外的项目,内部项目一般都是资源打包,所以不太妥。 base64也解决不了问题,因为有些字体就很大,不适合用这种方式。

新的思路

突然想到,如果我能通过webpack插件来把资源都改成微应用路径不就行了?于是找了个插件string-replace-webpack-plugin

var StringReplacePlugin = require("string-replace-webpack-plugin");

module.exports = {

module: {

loaders: [

// configure replacements for file patterns

{

test: /index.html$/,

loader: StringReplacePlugin.replace({

replacements: [

{

pattern: //ig,

replacement: function (match, p1, offset, string) {

return secrets.web[p1];

}

}

]})

}

]

},

plugins: [

// an instance of the plugin must be present

new StringReplacePlugin()

]

}

配置好了没有一点反应,不知道是不是因为老项目的webpack版本太低还是其他原因。然后还想到,我们项目有生产和测试环境,测试环境还有好多个,这种绝对路径替换的方案也不太行的通。

巧妙解决

在上面的思路基础上,再回想下现在的现象,就是资源文件总是会跑到主应用的路径上去,那如果把微应用的资源移到主应用中去,不就能找到了?

select{

width: 200px;

height: 30px;

padding: 4px 10px;

border: $border;

-webkit-appearance: none;

-moz-appearance: none;

appearance: none;

background-image: url("/select.png");

background-repeat: no-repeat;

background-position: right 10px center;

background-color: $white;

}

资源文件用绝对路径,同时,把资源放到主应用的public下面(基于框架,我们的框架放到这个目录会自动打包Copy到Dist) 最后,顺利加载:

总结

在官方的解决方案上找不到想要的结果,就只能自己因地制宜了。希望这个思路可以帮到你们,谢谢!

相关文章

搜素“洣水”的成语
365bet国内

搜素“洣水”的成语

⌛ 07-02 👁️‍🗨️ 9896
为什么月亮会有圆有缺?如果你认为是地球遮挡了阳光,那你就错了
欧洲最大的半岛在哪里,欧洲最大半岛斯堪的纳维亚的地理位置详解
还在愁手机可视电话怎么打?看这里就对了!
365骑士版app下载

还在愁手机可视电话怎么打?看这里就对了!

⌛ 07-02 👁️‍🗨️ 5094
小米6最新价格及购买渠道详解:官网、二手及电商平台价格对比
手机分期购买一期是多久?
bat365台湾入口

手机分期购买一期是多久?

⌛ 08-03 👁️‍🗨️ 8263