Webpack5 Federation

准备阅读

本文对前端基础有一定要求,推荐先熟读以下文章

一、Usage Example

1.1 app1 的组件定义

// 依赖略去
export default inject('AppState')((props) => {
  const { AppState: { currentLanguage: language } } = props;
  const IntlProviderAsync = useMemo(() => asyncLocaleProvider(language, () => import(`../../locale/${language}`)), []);

  return (
    <IntlProviderAsync>
      <StoreProvider {...props}>
        <ModalProvider>
          <MainView />
        </ModalProvider>
      </StoreProvider>
    </IntlProviderAsync>
  );
});

/* externalize: PageDesigner */

1.2 app2 的组件使用

<ExternalComponent
   system={{
      scope: 'lc',
      module: 'PageDesigner',
    }}
    modelId={tableObjectId}
    viewId={variableViewId}
    variableFlag
/>

二、Key Code

1.loadComponent.js

import React from 'react';

function loadComponent(scope, module, onError) {
  return async () => {
    // Initializes the share scope. This fills it with known provided modules from this build and all remotes
    await __webpack_init_sharing__('default');

    const container = window[scope]; // or get the container somewhere else
    // Initialize the container, it may provide shared modules
    if (!container) {
      throw new Error('加载了错误的importManifest.js,请检查服务版本');
    }
    try {
      await container.init(__webpack_share_scopes__.default);
      const factory = await window[scope].get(module);
      const Module = factory();
      return Module;
    } catch (e) {
      if (onError) {
        return onError(e);
      }
      throw e;
    }
  };
}

export default loadComponent;

2. ExternalComponent.js

/* eslint-disable no-underscore-dangle */
import React from 'react';
import { loadComponent, useManifest } from './LoadComponent.js';
import Loading from '../loading';

const cache = new Map();

function getComponent({ scope, module }, ErrorComponent = null) {
  const scopeItem = cache.get(scope) || new Map();
  cache.set(scope, scopeItem);
  const component = scopeItem.get(module);
  if (component) {
    return component;
  }
  const lazyComponent = React.lazy(
    loadComponent(scope, module, (error) => {
      console.error(error);
      return {
        default: () => ErrorComponent,
      };
    }),
  );
  scopeItem.set(module, lazyComponent);
  return lazyComponent;
}

function ExternalComponent(props) {
  const { system, NotFound = Loading, ErrorComponent } = props;
  const { ready, failed } = useManifest(system);

  if (!props.system) {
    return <h2>Not system specified</h2>;
  }

  if (failed) {
    return <NotFound />;
  }

  if (!ready) {
    return <Loading />;
  }

  const Component = getComponent(system, ErrorComponent);

  return (
    <React.Suspense fallback={<Loading />}>
      <Component {...props} />
    </React.Suspense>
  );
}

export default ExternalComponent;

三、如何实现

以下是封装的前端框架源码解读,本着学习的心态对核心点画圈圈;主要实现用注释标注的方式,实现跨应用组件加载

  • 文件io读取
  • 正则匹配
  • 动态构建federation配置

3.1 代码简化对比

federation核心属性

  • name
  • library
  • exposes/ remotes
  • shared
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值