关于微前端实现原理与ngx-planet(三)客制化 置顶!

Updated on with 0 views and 0 comments

客制化

  由于公司和公司的业务不同,所以在 ngx-planet 的基础上,需要作出一些针对于业务的拓展

  目前分出四个基础项目

  @yunzai/stars:封装了 用户认证,元素权限,i18n 等系统初始化信息的内容,需要发包的,意为繁星。

  star-universe: portal 项目,所有子前端项目的入口,意为宇宙。

  star-dust:一些可能会通用的 components 都放到这个项目里,统一管理,意为星尘。

  star-uranus:模版项目,意为天王星。

开发环境

  image.png

  可以看到桌面共有四个编辑器,开发时需要跑起其中三个项目。
star-universe,star-dust,star-uranus

@yunzai/stars

  因为是基础包,所以扩展了哪些功能点,先做一个介绍,因为发包,所以 planet 前缀都被我改名成为了 star 前缀,针对于 ngx-planet 加载过程请看前一篇link start

  接下来看项目结构

  image.png

  首先基于 ngx-planet 加入了 auth,config,i18n,providers,stomp,token,user 这些文件夹

module

  针对于 Module 做出了以下改良
image.png

  加入了 TranslateModule 来写 i18n
加入了 Inject 的静态配置类 StarConfig

/*
 * @Author: ferried
 * @Email: harlancui@outlook.com
 * @Date: 2021-02-01 08:59:04
 * @LastEditTime: 2021-02-03 09:37:51
 * @LastEditors: ferried
 * @Description: Basic description
 * @FilePath: /stars-package/projects/stars/src/star-config.ts
 * @LICENSE: Apache-2.0
 */

import { InjectionToken } from "@angular/core";
import { InjectableRxStompConfig } from "@stomp/ng2-stompjs";

/**
 * 配置接口
 */
export interface StarConfig {
  /**
   * 网关
   */
  gateway: string;
  /**
   * cas
   */
  cas: string;
  /**
   * 忽略地址
   */
  ignores: Array<string>;
  /**
   * 开发模式
   */
  dev?: {
    // 用户名
    username: string;
    // 密码
    password: string;
    // 是否开启网络
    network: boolean;
  };
  /**
   * 长连接
   */
  stomp?: InjectableRxStompConfig;
}

/**
 * inject token
 */
export const STAR_CONFIG = new InjectionToken<StarConfig>("STAR_CONFIG");

  这些配置在包中可以被 inject 到然后使用,方便开发,但是只有 portal 项目注入了配置,如何在其他子应用中使用呢,这里使用了 APP_INITIALIZER

  image.png

  提供了一个初始化的工程函数,返回一个 Promise 给 angular,配置到子应用中的 providers 中用来初始化各个子应用的 config
image.png

  具体如何实现呢

扩展 portalApplication

  image.png

  可以看到,portalApplication 被我扩展出了 6 个其他的属性,这些属性在 PortalApplication 被创建时由 portal的context使用inject 装入,这里区分 context 很重要

  image.png

  并放到了全局 window 下,那么子应用使用的时候就可以直接从 window 下获取了,但是比较怪,想要通过 构造器 注入使用应该怎么办呢

  可以单独提供一个 ConfigService

  image.png

  image.png

  这样子应用使用直接注入的方式就可以拿到 config 配置

  image.png

  这样就做到了通过 windowportal 流转,service 共享的机制

portal provider 和 star provider

portal

  image.png

  这是整体 portalprovider

export function PortalStartupServiceFactory(
  authStartupService: AuthStartupService,
  i18nStartupService: I18nStartupService,
  configStartupService: ConfigStartupService,
  portalInfoStartupService: PortalInfoStartupService
): Function {
  return () => {
    return new Promise((resolve, reject) => {
// 先将config共享
      configStartupService.load().then(() => {
// portal进行用户认证决定跳入登录还是进入子应用
        authStartupService.load().then(() => {
// 初始化一些logo,footer等乱七八糟的信息
          portalInfoStartupService.load().then(() => {
// 初始化i18n远程拉过来的语言列表等
            i18nStartupService.load().then(() => {
              resolve(true);
            });
          });
        });
      });
    });
  };
}

  使用时,在 star-universe 中直接加入即可
image.png

  如图可见,在使用 YunzaiStarsModule 的时候注入了一些配置信息,config 就是通过这些从 portal 注入的信息去分享的 service,然后 providers 中也加载了一些 APPINIT_PROVIDES,剩下的 HTTP_INTERCEPTORS 是两个拦截器,分别在 httpHeaders 中加入了一些配置信息

star

  image.png

  上图是 star 的初始化操作,只共享了 config 和 i18n 的信息。
这里 i18n 是必须要加入的,使用 translate pipe 时是从当前的 module 中提取的 translateService 去进行翻译的,所以子应用不初始化 i18n 会导致,子应用中的模块 module 没有加载 i18n的语言列表 从而 translate 管道不生效,和 config 共享机制相同

  image.png

  上图为 子应用的 初始化 Providers,和 portal 不同的是,无需注入 额外的配置了 因为通过 providerswindow 流转到子应用的 service 中了。

关于集成 ng-zorro-antd

  正常 ng-add 进 ng-zorro-antd 包,然后修改 webpack 匹配的 scssless,其中有一个 bug,无论使用 ngx-planet 的 scss 或是 ng-zorro-antdless 都会出现,已经提了issues

  目前的解决方法是建立一个 component.less/scss 然后引入全局的 `style.less/css'
image.png

  image.png

portal 的 extra-webpack-config

  image.png

子应用的 extra-webpack-config

  image.png

portal 作为 layout

  以下为 portal 的路由
image.png

  在 layout 中加入挂载点

  image.png

  就可以做到 layout 在 portal 中,其余页面分布在子应用中了

事件注册,组件注册扩展

  image.png

  事件注册加了一层 应用事件 关联的 map

  这样就可以知道哪些应用放出了哪些事件

  image.png

  组件注册加了一层 应用组件 的关联 map

  这样就可以知道哪些应用放出了哪些组件

stomp 长链接再配置

  由于 portal 是整个应用群的入口,所以是常驻的,stomp 模块直接加在 portal 里注册一个事件即可全应用通用,但是在部署的时候会有域名/无域名/有 https/无 https,开发人员不想每次都重新打包怎么办呢

  我们修改注入到 RxStompServiceConfig
image.png

  提供我们自己的 Config

/*
 * @Author: ferried
 * @Email: harlancui@outlook.com
 * @Date: 2021-02-03 09:35:56
 * @LastEditTime: 2021-02-03 09:38:52
 * @LastEditors: ferried
 * @Description: Basic description
 * @FilePath: /stars-package/projects/stars/src/stomp/stomp.ts
 * @LICENSE: Apache-2.0
 */
import { RxStompConfig } from "@stomp/rx-stomp";
import { StarConfig } from "../config/star-config";

export function YzStompConfigFactory(starConfig: StarConfig): RxStompConfig {
  const stomp: RxStompConfig = new RxStompConfig();
  if (starConfig.stomp) {
    let brokerUrl = null;

    if (document.location.protocol === "https:" && starConfig.stomp.brokerURL) {
      brokerUrl = `wss://${window.location.host}${starConfig.stomp.brokerURL}`;
    }
    if (document.location.protocol === "http:" && starConfig.stomp.brokerURL) {
      brokerUrl = `ws://${window.location.host}${starConfig.stomp.brokerURL}`;
    }

    if (starConfig.stomp && starConfig.stomp.brokerURL) {
      if (
        starConfig.stomp.brokerURL.split(":")[0] === "wss" ||
        starConfig.stomp.brokerURL.split(":")[0] === "ws"
      ) {
        brokerUrl = starConfig.stomp.brokerURL;
      }
    }

    if (brokerUrl) {
      stomp.brokerURL = brokerUrl;
    }

    if (starConfig.stomp.connectHeaders && starConfig.stomp.connectHeaders) {
      stomp.connectHeaders = starConfig.stomp.connectHeaders;
    }

    if (starConfig.stomp.heartbeatIncoming) {
      stomp.heartbeatIncoming = starConfig.stomp.heartbeatIncoming;
    }
    if (starConfig.stomp.heartbeatOutgoing) {
      stomp.heartbeatOutgoing = starConfig.stomp.heartbeatOutgoing;
    }
    if (starConfig.stomp.reconnectDelay) {
      stomp.reconnectDelay = starConfig.stomp.reconnectDelay;
    }
  }
  return stomp;
}

关于 cli

  等到项目完成后要加入 schematic 然后通过 ng add @yunzai/stars 来自动初始化项目,目前 star-uranus 模版没调好所以还无法做

  具体如何做可以通过 ng-zorro-antd 来实现一下
cli


标题:关于微前端实现原理与ngx-planet(三)客制化
作者:fe
地址:https://blog.eiyouhe.com/articles/2021/02/05/1612514513154.html