qiankun 中使用Angular 实践

qiankun 中使用Angular 实践

最近把玩qiankun,基座跟微应用都是使用Angular,这两个应用都是放到docker 容器中,结果安装官方的配置后,拉起环境一路的坑。记录一二,防止后来者也入坑。先介绍一下环境的情况

  • mainapp
    • Angular15,
    • Docker 本机的4300端口映射到容器内的4200
  • subapp
    • Angualr15,
    • Docker 本机的4301端口映射到容器内的4200

简单来说就是Angualr 都是使用默认的4200,映射到host 的不同端口

问题一,主应用/微应用无法访问

  • 解决办法,package.json 中加上如下
"scripts": {
    "ng": "ng",
--    "start": "ng serve",
++    "start": "ng serve --host 0.0.0.0",
  }

默认情况下,angular或者说webpack 监听的是localhost 的4200端口,在我们的场景里面是docker容器的回环ip 的4200端口,然而我们是从host机器的浏览器开始访问的,尽管端口进行了映射。这里指定了host 0.0.0.0,意思就是告诉webpack 这个网站对于整个局域网开放。也就是说局域网上面的任何机器都可以通过ip访问这个网站。

问题二,从主应用访问微应用后,页面就开始不停的reload,出现闪烁的现象。不停的重载,刷新。

  • 解决办法。这边有个上下文,微应用的改造是依照qiankun官网的改造指南
    修改custom-webpack.config.js
const appName = require('./package.json').name;
module.exports = {
  devServer: {
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
++    client:{
++      webSocketUR:{
++        hostName:'0.0.0.0',
++        port:4301  // 可以依据你的实践端口号修改
++      }
++    }
  },
  output: {
    library: `${appName}-[name]`,
    libraryTarget: 'umd',
    jsonpFunction: `webpackJsonp_${appName}`,
  },
};
  • 为什么会出现闪烁的现象。原因是浏览器中的webpackdeverserver(wds) 的客户段无法连接到正确的wds 的服务端,实际上,它是连接到基座的wds 上了,所以导致了页面重新加载。关于wds 的工作流程请参考下图
    alt wds工作流程
    • 默认情况下webSocketURL 是长这样的webSocketURL: 'auto://0.0.0.0:0/ng-cli-ws', 它实际上会连接到当前基座的wds。这就是问题所在。
      alt wds错误

问题三,当我们在微应用中开发时,当页面自动刷新后,会报ngZone的错误

Error: NG0909: Expected to not be in Angular Zone, but it is!
问题也是显而易见的,由于ngZone 是在主应用被导入的,微应用中是没有被导入。所以微应用刷新的时候会报这个错。githubIssuer

  • 解决办法
    由于我的基座跟微应用都是Angular 15,我这边有个比较简单的解决办法
let app: void | NgModuleRef<AppModule>;
async function render() {  
--  // app = await platformBrowserDynamic().bootstrapModule(AppModule)
++  app = await platformBrowserDynamic().bootstrapModule(AppModule, { ngZone: (window as any).ngZone })
   .catch(err => console.error(err));
}

在主应用的app.module.ts 里面 将ngZone 存放到window 里面

constructor(private ngZone: NgZone) {
    (window as any).ngZone = this.ngZone;
  }
  • 更加优雅的解决方法,就是使用 single-spa-angular这个包,上面谈到的所有问题,它都解决了。
posted @ 2023-04-23 07:20  kongshu  阅读(486)  评论(0编辑  收藏  举报