umi icon indicating copy to clipboard operation
umi copied to clipboard

[热更新] 目前umi的的乾坤应用嵌套的子应用没有热更新

Open liuguang2016 opened this issue 2 years ago • 21 comments

项目分别是umi4.0.40中examples里的qiankun-master和qiankun-slave 项目地址:https://github.com/umijs/umi/tree/master/examples 分别启动项目后: image 进入slave image 代码中修改pages/home.ts中的HomePage内容,然后保存,但页面没有反应,热更新没有生效

liuguang2016 avatar Dec 28 '22 02:12 liuguang2016

由于缺乏足够的信息,我们暂时关闭了该 Issue。请修改(不要回复) Issue 提供最小重现以重新开启。谢谢。

github-actions[bot] avatar Dec 28 '22 02:12 github-actions[bot]

需要给子应用指定 SOCKET_SERVER 到主应用的端口。 我尝试创建了.env文件并添加了SOCKET_SERVER image 但是并没有生效 @fz6m

liuguang2016 avatar Dec 28 '22 09:12 liuguang2016

  # 子应用启动命令
  SOCKET_SERVER=http://localhost:8888/ max dev

用了启动命令还是不行 image

要不麻烦直接更新下demo,我们直接下载demo来验证 @fz6m

liuguang2016 avatar Dec 29 '22 02:12 liuguang2016

同时还发现,目前子应用开启socket_server后,只有ping没有响应 image

liuguang2016 avatar Dec 29 '22 02:12 liuguang2016

不好意思,修改 qiankun-masterpackage.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 avatar Dec 29 '22 02:12 fz6m

按该方法,目前子应用可以热更新了 不过又来了个新问题,现在是全量更新,更改子应用内容,主应用也会刷新 image @fz6m 有解法吗?

liuguang2016 avatar Dec 29 '22 03:12 liuguang2016

我理解子应用独立开发就行了,没必要把主应用也启动起来套壳开发。

@stormslowly pshu 老师,子应用现在套壳热更新的场景你们怎么做的呀,有解法么 🌹

fz6m avatar Dec 29 '22 05:12 fz6m

我理解子应用独立开发就行了,没必要把主应用也启动起来套壳开发。

@stormslowly pshu 老师,子应用现在套壳热更新的场景你们怎么做的呀,有解法么 🌹

@fz6m 目前debug源码发现是每次触子应用发热更新时,请求的是主应用的update.json,parse时报错,就直接window.loaction.reload了。 其实这是主应用更不没变化,拿到的update.json就是空的,所以报错了 目前还没找到解决办法,如果有结果麻烦回复下

liuguang2016 avatar Jan 05 '23 02:01 liuguang2016

子应用 dev 启动的时候有没有通过 环境变量 SOCKET_SERVER 指定到自己的启动端口上

stormslowly avatar Jan 05 '23 06:01 stormslowly

子应用加了SOCKET_SERVER,如下 image 但是没有用 @stormslowly 是加的方式有问题吗?

liuguang2016 avatar Jan 10 '23 01:01 liuguang2016

子应用加了SOCKET_SERVER,如下 image 但是没有用 @stormslowly 是加的方式有问题吗?

感觉你的配置文件 是配置 SOCKET_SERVER='http://..... max dev'了 你先删掉 .env 文件 直接用命令行配置 环境变量的方式试试看

# 在命令行执行 
SOCKET_SERVER=http://localhost:5555 PORT=5555 npx max dev

stormslowly avatar Jan 10 '23 03:01 stormslowly

@stormslowly 按你的方法配置了还是全量更新

zyh2123606 avatar Jan 10 '23 08:01 zyh2123606

子应用加了SOCKET_SERVER,如下 image 但是没有用 @stormslowly 是加的方式有问题吗?

感觉你的配置文件 是配置 SOCKET_SERVER='http://..... max dev'了 你先删掉 .env 文件 直接用命令行配置 环境变量的方式试试看

# 在命令行执行 
SOCKET_SERVER=http://localhost:5555 PORT=5555 npx max dev

直接写在命令行也没有生效 image @stormslowly 大佬们是不可以直接更新下官方的demo?

liuguang2016 avatar Jan 10 '23 08:01 liuguang2016

多个子应用同时启动的话如何解决

mafeifeifeife avatar Jan 11 '23 06:01 mafeifeifeife

👍 确实有问题,需要看下 qiankun 下为啥 HMR 不更新了

PR welcome。

stormslowly avatar Jan 11 '23 07:01 stormslowly

+1,umi4 微前端开发时,子应用无法热更新

CristalFJJ avatar Feb 24 '23 04:02 CristalFJJ

换了SOCKET_SERVER生效了,也能正常收到消息,但是还是无法更新,必须要刷新页面才可以解决。

PopperLi avatar Jun 19 '23 09:06 PopperLi

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 里直接实现掉了

kuitos avatar Jul 11 '23 02:07 kuitos

一个比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,
    }
}

jk4235 avatar Aug 10 '23 08:08 jk4235

@fz6m 我个人认为,环境变量 SOCKET_SERVER 这种方式不太合理, 将 port 传递到client 中应该能避免掉这个问题。

多个子应用同时本地开发,因为服务端口不同,ws 的端口应该也跟着变。所以我认为传递参数是最佳的方案, 这个还可以避免端口占用,自动切换端口后,ws port 对不上的问题。

我认为选择做在qiankun插件中也不是一个好的解决方案。 因为目前市面上微前端方案很多,umi 应该是作为一个独立的前端框架。

nanianlisao avatar Apr 24 '24 02:04 nanianlisao

到目前为止,还是放弃套壳开发这种想法吧。

一是目前没有对套壳开发的强诉求。

二是目前市面上所有的微前端方案,无论采用什么套壳热更新手段,在应用复杂一点肯定会触发全量更新或者 HMR 失效,最好的办法就是子应用独立开发。

fz6m avatar Apr 25 '24 18:04 fz6m