umi
umi copied to clipboard
[热更新] 目前umi的的乾坤应用嵌套的子应用没有热更新
项目分别是umi4.0.40中examples里的qiankun-master和qiankun-slave
项目地址:https://github.com/umijs/umi/tree/master/examples
分别启动项目后:
进入slave
代码中修改pages/home.ts中的HomePage内容,然后保存,但页面没有反应,热更新没有生效
由于缺乏足够的信息,我们暂时关闭了该 Issue。请修改(不要回复) Issue 提供最小重现以重新开启。谢谢。
需要给子应用指定
SOCKET_SERVER
到主应用的端口。 我尝试创建了.env文件并添加了SOCKET_SERVER但是并没有生效 @fz6m
# 子应用启动命令 SOCKET_SERVER=http://localhost:8888/ max dev
用了启动命令还是不行
要不麻烦直接更新下demo,我们直接下载demo来验证 @fz6m
同时还发现,目前子应用开启socket_server后,只有ping没有响应
不好意思,修改 qiankun-master
的 package.json
:
// package.json
"scripts": {
- "dev": "cross-env PORT=8888 max dev",
+ "dev": "cross-env PORT=8888 SOCKET_SERVER=http://localhost:5555/ max dev",
},
即可在 http://localhost:8888/
下,修改子应用更新页面。
按该方法,目前子应用可以热更新了
不过又来了个新问题,现在是全量更新,更改子应用内容,主应用也会刷新
@fz6m 有解法吗?
我理解子应用独立开发就行了,没必要把主应用也启动起来套壳开发。
@stormslowly pshu 老师,子应用现在套壳热更新的场景你们怎么做的呀,有解法么 🌹
我理解子应用独立开发就行了,没必要把主应用也启动起来套壳开发。
@stormslowly pshu 老师,子应用现在套壳热更新的场景你们怎么做的呀,有解法么 🌹
@fz6m 目前debug源码发现是每次触子应用发热更新时,请求的是主应用的update.json,parse时报错,就直接window.loaction.reload了。 其实这是主应用更不没变化,拿到的update.json就是空的,所以报错了 目前还没找到解决办法,如果有结果麻烦回复下
子应用加了SOCKET_SERVER,如下
但是没有用 @stormslowly 是加的方式有问题吗?
感觉你的配置文件 是配置 SOCKET_SERVER='http://..... max dev'了 你先删掉 .env 文件 直接用命令行配置 环境变量的方式试试看
# 在命令行执行
SOCKET_SERVER=http://localhost:5555 PORT=5555 npx max dev
@stormslowly 按你的方法配置了还是全量更新
子应用加了SOCKET_SERVER,如下
但是没有用 @stormslowly 是加的方式有问题吗?
感觉你的配置文件 是配置 SOCKET_SERVER='http://..... max dev'了 你先删掉 .env 文件 直接用命令行配置 环境变量的方式试试看
# 在命令行执行 SOCKET_SERVER=http://localhost:5555 PORT=5555 npx max dev
直接写在命令行也没有生效
@stormslowly
大佬们是不可以直接更新下官方的demo?
多个子应用同时启动的话如何解决
👍 确实有问题,需要看下 qiankun 下为啥 HMR 不更新了
PR welcome。
+1,umi4 微前端开发时,子应用无法热更新
换了SOCKET_SERVER
生效了,也能正常收到消息,但是还是无法更新,必须要刷新页面才可以解决。
umi4 里没实现自动设置 SOCKET_SERVER
https://github.com/umijs/umi/blob/master/packages/plugins/src/qiankun/slave.ts#L191
umi3 qiankun 插件实现了 https://github.com/umijs/plugins/blob/master/packages/plugin-qiankun/src/slave/index.ts#L144 @fz6m 可以看下是不是可以在 umi4 里直接实现掉了
一个比location.reload稍微好一些的解决方案, 整个子应用会rerender, location.reload实在是太慢了
.umirc.ts
fastRefresh: false,
test: false,
.umirc.dev.ts
import { defineConfig } from "@umijs/max";
export default defineConfig({
define: {
"process.env": {
SOCKET_SERVER: "http://localhost:8002", // 这里换成子应用实际的端口
},
},
});
plugin.ts
import type { IApi } from "@umijs/max";
export default (api: IApi) => {
api.addEntryImports(() => {
return {
source: "umi",
specifier: "{ __getRoot }",
};
});
api.addEntryCode(() => {
return `
// hot module replacement
// @ts-ignore
if (module.hot) {
// @ts-ignore
module.hot.accept("./core/route", () => {
const root = __getRoot()
root.unmount() // for react 18, 如果你是其他react版本,请用ReactDOM.unmountComponentAtNode(container)方式卸载组件;
render()
})
}
`;
})
}
bonus: 子应用启动的时候,主应用去加载会挂掉,配置proxy即可避免
主应用 umirc.ts
proxy: {
[`/__umi/api/bundle-status`]: {
target: `http://localhost:${app.port}`,
changeOrigin: true,
}
}
@fz6m 我个人认为,环境变量 SOCKET_SERVER 这种方式不太合理, 将 port 传递到client 中应该能避免掉这个问题。
多个子应用同时本地开发,因为服务端口不同,ws 的端口应该也跟着变。所以我认为传递参数是最佳的方案, 这个还可以避免端口占用,自动切换端口后,ws port 对不上的问题。
我认为选择做在qiankun插件中也不是一个好的解决方案。 因为目前市面上微前端方案很多,umi 应该是作为一个独立的前端框架。
到目前为止,还是放弃套壳开发这种想法吧。
一是目前没有对套壳开发的强诉求。
二是目前市面上所有的微前端方案,无论采用什么套壳热更新手段,在应用复杂一点肯定会触发全量更新或者 HMR 失效,最好的办法就是子应用独立开发。