@ice/mf-runtime 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @ali/ice-mf-runtime
2
+
3
+ 组件功能描述
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ $ npm i @ali/ice-mf-runtime --save
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```jsx
14
+ import IceMfRuntime from '@ali/ice-mf-runtime';
15
+ ```
@@ -0,0 +1,62 @@
1
+ import * as React from 'react';
2
+ interface FallBackOptions {
3
+ Original: React.ComponentType<any>;
4
+ remoteVersion?: () => string;
5
+ hostVersion?: () => string;
6
+ remoteReactDOM: () => typeof import('react-dom');
7
+ remoteReact: () => typeof import('react');
8
+ }
9
+ export declare const FallBack: ({ Original, remoteReactDOM, remoteReact, }: FallBackOptions) => {
10
+ new (props: {}): {
11
+ containerRef: React.RefObject<HTMLDivElement>;
12
+ componentDidMount(): void;
13
+ componentDidUpdate(): void;
14
+ componentWillUnmount(): void;
15
+ mountOriginalComponent(shouldRender?: boolean): void;
16
+ render(): React.JSX.Element;
17
+ context: unknown;
18
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<{}>) => {} | Pick<{}, K>) | Pick<{}, K>, callback?: () => void): void;
19
+ forceUpdate(callback?: () => void): void;
20
+ readonly props: Readonly<{}>;
21
+ state: Readonly<{}>;
22
+ refs: {
23
+ [key: string]: React.ReactInstance;
24
+ };
25
+ shouldComponentUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): boolean;
26
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
27
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{}>, prevState: Readonly<{}>): any;
28
+ componentWillMount?(): void;
29
+ UNSAFE_componentWillMount?(): void;
30
+ componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
31
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
32
+ componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
33
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
34
+ };
35
+ new (props: {}, context: any): {
36
+ containerRef: React.RefObject<HTMLDivElement>;
37
+ componentDidMount(): void;
38
+ componentDidUpdate(): void;
39
+ componentWillUnmount(): void;
40
+ mountOriginalComponent(shouldRender?: boolean): void;
41
+ render(): React.JSX.Element;
42
+ context: unknown;
43
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<{}>) => {} | Pick<{}, K>) | Pick<{}, K>, callback?: () => void): void;
44
+ forceUpdate(callback?: () => void): void;
45
+ readonly props: Readonly<{}>;
46
+ state: Readonly<{}>;
47
+ refs: {
48
+ [key: string]: React.ReactInstance;
49
+ };
50
+ shouldComponentUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): boolean;
51
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
52
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{}>, prevState: Readonly<{}>): any;
53
+ componentWillMount?(): void;
54
+ UNSAFE_componentWillMount?(): void;
55
+ componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
56
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
57
+ componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
58
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
59
+ };
60
+ contextType?: React.Context<any>;
61
+ };
62
+ export {};
@@ -0,0 +1,43 @@
1
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
+ import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime";
3
+ import * as React from 'react';
4
+ class Component extends React.Component {
5
+ render() {
6
+ const { containerRef } = this.props;
7
+ return /*#__PURE__*/ _jsx("div", {
8
+ ref: containerRef
9
+ });
10
+ }
11
+ }
12
+ export const FallBack = ({ Original, remoteReactDOM, remoteReact })=>{
13
+ const ReactDOM = remoteReactDOM();
14
+ const React = remoteReact();
15
+ class WrappedComponent extends React.Component {
16
+ componentDidMount() {
17
+ this.mountOriginalComponent(true);
18
+ }
19
+ componentDidUpdate() {
20
+ this.mountOriginalComponent();
21
+ }
22
+ componentWillUnmount() {
23
+ if (this.containerRef.current) {
24
+ ReactDOM.unmountComponentAtNode(this.containerRef.current);
25
+ }
26
+ }
27
+ mountOriginalComponent(shouldRender = false) {
28
+ const element = React.createElement(Original, this.props);
29
+ const renderMethod = shouldRender ? ReactDOM.render : ReactDOM.hydrate;
30
+ renderMethod(element, this.containerRef.current);
31
+ }
32
+ render() {
33
+ return /*#__PURE__*/ _jsx(Component, {
34
+ containerRef: this.containerRef
35
+ });
36
+ }
37
+ constructor(...args){
38
+ super(...args);
39
+ _define_property(this, "containerRef", React.createRef());
40
+ }
41
+ }
42
+ return WrappedComponent;
43
+ };
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ interface RemoteModuleOptions {
3
+ module: string;
4
+ scope: string;
5
+ runtime?: {
6
+ react: typeof import('react');
7
+ reactDOM: typeof import('react-dom');
8
+ };
9
+ publicPath?: string;
10
+ LoadingComponent?: React.ReactNode;
11
+ }
12
+ export declare const RemoteModule: ({ module, scope, runtime, publicPath, LoadingComponent, }: RemoteModuleOptions) => string | number | true | Iterable<React.ReactNode> | React.JSX.Element;
13
+ export {};
@@ -0,0 +1,63 @@
1
+ import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime";
2
+ import { loadRemote } from '@module-federation/runtime';
3
+ import * as React from 'react';
4
+ import { useEffect, useState } from 'react';
5
+ import { FallBack } from './FallBack';
6
+ import { setFederatedModulePublicPath } from './set-public-path';
7
+ function useDynamicImport({ module, scope }) {
8
+ const [component, setComponent] = useState(null);
9
+ useEffect(()=>{
10
+ if (!module || !scope) return;
11
+ const loadComponent = async ()=>{
12
+ try {
13
+ const res = await loadRemote(`${scope}/${module}`);
14
+ setComponent(res);
15
+ } catch (error) {
16
+ console.error(`Error loading remote module ${scope}/${module}:`, error);
17
+ }
18
+ };
19
+ loadComponent();
20
+ }, [
21
+ module,
22
+ scope
23
+ ]);
24
+ return component;
25
+ }
26
+ export const RemoteModule = ({ module, scope, runtime, publicPath, LoadingComponent })=>{
27
+ var _remoteModule;
28
+ if (publicPath) {
29
+ setFederatedModulePublicPath(scope, publicPath);
30
+ }
31
+ const remoteModule = useDynamicImport({
32
+ module,
33
+ scope
34
+ });
35
+ let Component = null;
36
+ if ((_remoteModule = remoteModule) === null || _remoteModule === void 0 ? void 0 : _remoteModule.default) {
37
+ if (runtime) {
38
+ const { react, reactDOM } = runtime;
39
+ const w = FallBack({
40
+ Original: remoteModule.default,
41
+ remoteReact: ()=>react,
42
+ remoteReactDOM: ()=>reactDOM
43
+ });
44
+ Component = w;
45
+ } else {
46
+ Component = /*#__PURE__*/ React.lazy(()=>Promise.resolve({
47
+ default: remoteModule.default
48
+ }));
49
+ }
50
+ } else {
51
+ Component = remoteModule;
52
+ }
53
+ const Loading = LoadingComponent || /*#__PURE__*/ _jsx("div", {
54
+ children: "Loading..."
55
+ });
56
+ if (Component) {
57
+ return /*#__PURE__*/ _jsx(React.Suspense, {
58
+ fallback: Loading,
59
+ children: /*#__PURE__*/ _jsx(Component, {})
60
+ });
61
+ }
62
+ return Loading;
63
+ };
@@ -0,0 +1,5 @@
1
+ import type { ExtendedUserOptions } from './types';
2
+ export { loadRemote, registerPlugins } from '@module-federation/runtime';
3
+ export * from './FallBack';
4
+ export * from './RemoteModule';
5
+ export declare function init(options: ExtendedUserOptions): void;
@@ -0,0 +1,11 @@
1
+ import { registerPlugins, init as mfInit } from '@module-federation/runtime';
2
+ import { runtimePlugin } from './runtime-plugin';
3
+ export { loadRemote, registerPlugins } from '@module-federation/runtime';
4
+ export * from './FallBack';
5
+ export * from './RemoteModule';
6
+ export function init(options) {
7
+ mfInit(options);
8
+ registerPlugins([
9
+ runtimePlugin()
10
+ ]);
11
+ }
@@ -0,0 +1,27 @@
1
+ import type { ExtraInfo, ExtendedUserOptions } from './types';
2
+ export interface RemoteModuleInfo {
3
+ key: string;
4
+ name: string;
5
+ entry: string;
6
+ hostName: string;
7
+ version?: string;
8
+ extraInfo?: ExtraInfo;
9
+ }
10
+ export interface HostRemoteInfo {
11
+ keys: Set<string>;
12
+ nameKeyMap: Map<string, string>;
13
+ conflictingModules: Set<string>;
14
+ }
15
+ declare global {
16
+ interface Window {
17
+ __MF_GLOBAL_STORE__: {
18
+ remotes: Map<string, RemoteModuleInfo>;
19
+ hostRemotes: Map<string, HostRemoteInfo>;
20
+ };
21
+ }
22
+ }
23
+ export declare function initGlobalStore(options: ExtendedUserOptions): void;
24
+ export declare function generateRemoteKey(name: string, entry: string): string;
25
+ export declare function getRemoteInfoFromStore(hostName: string, remoteName: string): RemoteModuleInfo | undefined;
26
+ export declare function hasConflict(hostName: string, remoteName: string): boolean;
27
+ export declare function getExtraInfo(hostName: string, remoteName: string): ExtraInfo;
@@ -0,0 +1,66 @@
1
+ export function initGlobalStore(options) {
2
+ if (!window.__MF_GLOBAL_STORE__) {
3
+ window.__MF_GLOBAL_STORE__ = {
4
+ remotes: new Map(),
5
+ hostRemotes: new Map()
6
+ };
7
+ }
8
+ const store = window.__MF_GLOBAL_STORE__;
9
+ const hostInfo = {
10
+ keys: new Set(),
11
+ nameKeyMap: new Map(),
12
+ conflictingModules: new Set()
13
+ };
14
+ // 更新每个 remote 模块的信息
15
+ options.remotes.forEach((remote)=>{
16
+ if (!remote.name) return;
17
+ const { entry } = remote;
18
+ const remoteKey = generateRemoteKey(remote.name, entry);
19
+ const newInfo = {
20
+ key: remoteKey,
21
+ name: remote.name,
22
+ entry,
23
+ hostName: options.name,
24
+ extraInfo: remote.extraInfo
25
+ };
26
+ // 记录这个 host 使用的 remote key 和 name 到 key 的映射
27
+ hostInfo.keys.add(remoteKey);
28
+ hostInfo.nameKeyMap.set(remote.name, remoteKey);
29
+ // 检查是否与现有模块冲突
30
+ for (const [, info] of store.remotes.entries()){
31
+ if (info.name === remote.name && info.entry !== entry) {
32
+ console.warn(`[Module Federation] Remote module "${remote.name}" has multiple versions:`, `\nHost "${info.hostName}": ${info.entry}`, `\nHost "${options.name}": ${entry}`);
33
+ // 在 host 环境中标记该模块存在冲突
34
+ hostInfo.conflictingModules.add(remote.name);
35
+ }
36
+ }
37
+ store.remotes.set(remoteKey, newInfo);
38
+ });
39
+ // 更新 host 的 remote 信息
40
+ store.hostRemotes.set(options.name, hostInfo);
41
+ }
42
+ // 生成 remote 模块的唯一标识
43
+ export function generateRemoteKey(name, entry) {
44
+ return `${name}@${entry}`;
45
+ }
46
+ export function getRemoteInfoFromStore(hostName, remoteName) {
47
+ const store = window.__MF_GLOBAL_STORE__;
48
+ const hostInfo = store.hostRemotes.get(hostName);
49
+ if (!hostInfo) return undefined;
50
+ const remoteKey = hostInfo.nameKeyMap.get(remoteName);
51
+ if (!remoteKey) return undefined;
52
+ return store.remotes.get(remoteKey);
53
+ }
54
+ // 检查指定的 remote 模块在当前 host 环境中是否存在冲突
55
+ export function hasConflict(hostName, remoteName) {
56
+ var _hostInfo;
57
+ const store = window.__MF_GLOBAL_STORE__;
58
+ const hostInfo = store.hostRemotes.get(hostName);
59
+ var _hostInfo_conflictingModules_has;
60
+ return (_hostInfo_conflictingModules_has = (_hostInfo = hostInfo) === null || _hostInfo === void 0 ? void 0 : _hostInfo.conflictingModules.has(remoteName)) !== null && _hostInfo_conflictingModules_has !== void 0 ? _hostInfo_conflictingModules_has : false;
61
+ }
62
+ export function getExtraInfo(hostName, remoteName) {
63
+ var _remoteInfo;
64
+ const remoteInfo = getRemoteInfoFromStore(hostName, remoteName);
65
+ return (_remoteInfo = remoteInfo) === null || _remoteInfo === void 0 ? void 0 : _remoteInfo.extraInfo;
66
+ }
@@ -0,0 +1,2 @@
1
+ import { type FederationRuntimePlugin } from '@module-federation/runtime';
2
+ export declare const runtimePlugin: () => FederationRuntimePlugin;
@@ -0,0 +1,101 @@
1
+ import * as React from 'react';
2
+ import { getExtraInfo, getRemoteInfoFromStore, hasConflict } from './mf-global-store';
3
+ const loadRemotePackagedReactAndRender = async (args)=>{
4
+ var _args_origin_options_shared_reactdom_, _args_origin_options_shared_reactdom, _args_origin_options_shared, _args_origin_options, _remoteInstance_options_shared_reactdom_, _remoteInstance_options_shared_reactdom, _remoteInstance_options_shared, _remoteInstance_options;
5
+ const hostVersion = ((_args_origin_options = args.origin.options) === null || _args_origin_options === void 0 ? void 0 : (_args_origin_options_shared = _args_origin_options.shared) === null || _args_origin_options_shared === void 0 ? void 0 : (_args_origin_options_shared_reactdom = _args_origin_options_shared['react-dom']) === null || _args_origin_options_shared_reactdom === void 0 ? void 0 : (_args_origin_options_shared_reactdom_ = _args_origin_options_shared_reactdom[0]) === null || _args_origin_options_shared_reactdom_ === void 0 ? void 0 : _args_origin_options_shared_reactdom_.version) || React.version;
6
+ const remoteInstance = __FEDERATION__.__INSTANCES__.find(// @ts-expect-error wrong type
7
+ (instance)=>instance.name === args.remote.name);
8
+ const remoteVersion = remoteInstance ? (_remoteInstance_options = remoteInstance.options) === null || _remoteInstance_options === void 0 ? void 0 : (_remoteInstance_options_shared = _remoteInstance_options.shared) === null || _remoteInstance_options_shared === void 0 ? void 0 : (_remoteInstance_options_shared_reactdom = _remoteInstance_options_shared['react-dom']) === null || _remoteInstance_options_shared_reactdom === void 0 ? void 0 : (_remoteInstance_options_shared_reactdom_ = _remoteInstance_options_shared_reactdom[0]) === null || _remoteInstance_options_shared_reactdom_ === void 0 ? void 0 : _remoteInstance_options_shared_reactdom_.version : false;
9
+ if (remoteVersion && hostVersion && remoteVersion !== hostVersion) {
10
+ var _sharedOptions_find;
11
+ const remoteReactDOM = await remoteInstance.loadShare('react-dom', {
12
+ resolver: (sharedOptions)=>(_sharedOptions_find = sharedOptions.find((i)=>i.version === remoteVersion)) !== null && _sharedOptions_find !== void 0 ? _sharedOptions_find : sharedOptions[0]
13
+ });
14
+ var _sharedOptions_find1;
15
+ const remoteReact = await remoteInstance.loadShare('react', {
16
+ resolver: (sharedOptions)=>(_sharedOptions_find1 = sharedOptions.find((i)=>i.version === remoteVersion)) !== null && _sharedOptions_find1 !== void 0 ? _sharedOptions_find1 : sharedOptions[0]
17
+ });
18
+ if (!remoteReact || !remoteReactDOM) {
19
+ return null;
20
+ }
21
+ const res = (await import('./FallBack')).FallBack;
22
+ return ()=>res({
23
+ Original: args.exposeModule.default,
24
+ remoteVersion: ()=>remoteVersion,
25
+ hostVersion: ()=>hostVersion,
26
+ remoteReactDOM: remoteReactDOM,
27
+ remoteReact: remoteReact
28
+ });
29
+ }
30
+ return null;
31
+ };
32
+ export const runtimePlugin = ()=>({
33
+ name: 'ice-runtime-plugin',
34
+ afterResolve (args) {
35
+ var _extraInfo;
36
+ const hostName = args.options.name;
37
+ const remoteName = args.remote.name;
38
+ const extraInfo = getExtraInfo(hostName, remoteName);
39
+ if ((_extraInfo = extraInfo) === null || _extraInfo === void 0 ? void 0 : _extraInfo.legacy) {
40
+ if (args.expose.startsWith('./')) {
41
+ args.expose = args.expose.slice(2);
42
+ }
43
+ }
44
+ return args;
45
+ },
46
+ async onLoad (args) {
47
+ var _args_origin_options_shared_reactdom_, _args_origin_options_shared_reactdom, _args_origin_options_shared, _args_origin_options, _extraInfo;
48
+ const hostName = args.origin.name;
49
+ const remoteName = args.remote.name;
50
+ const hostVersion = ((_args_origin_options = args.origin.options) === null || _args_origin_options === void 0 ? void 0 : (_args_origin_options_shared = _args_origin_options.shared) === null || _args_origin_options_shared === void 0 ? void 0 : (_args_origin_options_shared_reactdom = _args_origin_options_shared['react-dom']) === null || _args_origin_options_shared_reactdom === void 0 ? void 0 : (_args_origin_options_shared_reactdom_ = _args_origin_options_shared_reactdom[0]) === null || _args_origin_options_shared_reactdom_ === void 0 ? void 0 : _args_origin_options_shared_reactdom_.version) || React.version;
51
+ const extraInfo = getExtraInfo(hostName, remoteName);
52
+ if ((_extraInfo = extraInfo) === null || _extraInfo === void 0 ? void 0 : _extraInfo.external) {
53
+ const externalReact = extraInfo.external['react'];
54
+ const externalReactDOM = extraInfo.external['react-dom'];
55
+ if (externalReact && externalReactDOM) {
56
+ const remoteReact = ()=>window[externalReact];
57
+ const remoteReactDOM = ()=>window[externalReactDOM];
58
+ if (remoteReactDOM().version === hostVersion) {
59
+ console.log('[runtime Plugin onLoad] use same external react');
60
+ return args;
61
+ }
62
+ // 当 external 版本不一致,走降级渲染
63
+ const res = (await import('./FallBack')).FallBack;
64
+ return ()=>res({
65
+ Original: args.exposeModule.default,
66
+ remoteReactDOM: remoteReactDOM,
67
+ remoteReact: remoteReact
68
+ });
69
+ }
70
+ }
71
+ const fallBackRender = await loadRemotePackagedReactAndRender(args);
72
+ if (fallBackRender) {
73
+ return fallBackRender;
74
+ }
75
+ return args;
76
+ },
77
+ async beforeRequest (args) {
78
+ const remoteName = args.id.split('/')[0];
79
+ const hostName = args.options.name;
80
+ if (!hasConflict(hostName, remoteName)) {
81
+ return args;
82
+ }
83
+ const newRemoteInfo = getRemoteInfoFromStore(hostName, remoteName);
84
+ if (!newRemoteInfo) {
85
+ return args;
86
+ }
87
+ const requestRemote = args.options.remotes.find((remote)=>remote.name === remoteName);
88
+ if (requestRemote) {
89
+ requestRemote.entry = newRemoteInfo.entry;
90
+ }
91
+ const hostInstance = __FEDERATION__.__INSTANCES__.find((instance)=>instance.name === hostName);
92
+ if (hostInstance) {
93
+ hostInstance.moduleCache.delete(remoteName);
94
+ hostInstance.options.remotes.find((remote)=>remote.name === remoteName).entry = newRemoteInfo.entry;
95
+ }
96
+ args.origin.moduleCache.delete(remoteName);
97
+ // @ts-expect-error for global module
98
+ window[remoteName] = null;
99
+ return args;
100
+ }
101
+ });
@@ -0,0 +1,2 @@
1
+ export declare const ensureSlash: (input: string, needSlash: boolean, position: 'tail' | 'head') => string;
2
+ export declare const setFederatedModulePublicPath: (scope: string, publicPath: string) => void;
@@ -0,0 +1,28 @@
1
+ export const ensureSlash = (input, needSlash, position)=>{
2
+ if (input == null) return input;
3
+ if (position === 'head') {
4
+ const startWithSlash = input.startsWith('/');
5
+ if (startWithSlash && !needSlash) {
6
+ return input.slice(1);
7
+ } else if (!startWithSlash && needSlash) {
8
+ return `/${input}`;
9
+ }
10
+ return input;
11
+ } else if (position === 'tail') {
12
+ const endsWithSlash = input.endsWith('/');
13
+ if (endsWithSlash && !needSlash) {
14
+ return input.substr(0, input.length - 1);
15
+ } else if (!endsWithSlash && needSlash) {
16
+ return `${input}/`;
17
+ } else {
18
+ return input;
19
+ }
20
+ } else {
21
+ return input;
22
+ }
23
+ };
24
+ export const setFederatedModulePublicPath = (scope, publicPath)=>{
25
+ const publicPathReference = `${scope}_public_path`;
26
+ // @ts-expect-error for global public path
27
+ window[publicPathReference] = ensureSlash(publicPath, true, 'tail');
28
+ };
@@ -0,0 +1,12 @@
1
+ import type { UserOptions } from '@module-federation/runtime-core';
2
+ import type { Remote } from '@module-federation/runtime-core/dist/src/types';
3
+ export interface ExtraInfo {
4
+ external?: Record<string, string>;
5
+ legacy?: boolean;
6
+ }
7
+ export type ExtendedRemote = Remote & {
8
+ extraInfo?: ExtraInfo;
9
+ };
10
+ export interface ExtendedUserOptions extends Omit<UserOptions, 'remotes'> {
11
+ remotes: ExtendedRemote[];
12
+ }
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ /// <reference types="@ice/pkg/types" />
@@ -0,0 +1,62 @@
1
+ import * as React from 'react';
2
+ interface FallBackOptions {
3
+ Original: React.ComponentType<any>;
4
+ remoteVersion?: () => string;
5
+ hostVersion?: () => string;
6
+ remoteReactDOM: () => typeof import('react-dom');
7
+ remoteReact: () => typeof import('react');
8
+ }
9
+ export declare const FallBack: ({ Original, remoteReactDOM, remoteReact, }: FallBackOptions) => {
10
+ new (props: {}): {
11
+ containerRef: React.RefObject<HTMLDivElement>;
12
+ componentDidMount(): void;
13
+ componentDidUpdate(): void;
14
+ componentWillUnmount(): void;
15
+ mountOriginalComponent(shouldRender?: boolean): void;
16
+ render(): React.JSX.Element;
17
+ context: unknown;
18
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<{}>) => {} | Pick<{}, K>) | Pick<{}, K>, callback?: () => void): void;
19
+ forceUpdate(callback?: () => void): void;
20
+ readonly props: Readonly<{}>;
21
+ state: Readonly<{}>;
22
+ refs: {
23
+ [key: string]: React.ReactInstance;
24
+ };
25
+ shouldComponentUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): boolean;
26
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
27
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{}>, prevState: Readonly<{}>): any;
28
+ componentWillMount?(): void;
29
+ UNSAFE_componentWillMount?(): void;
30
+ componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
31
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
32
+ componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
33
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
34
+ };
35
+ new (props: {}, context: any): {
36
+ containerRef: React.RefObject<HTMLDivElement>;
37
+ componentDidMount(): void;
38
+ componentDidUpdate(): void;
39
+ componentWillUnmount(): void;
40
+ mountOriginalComponent(shouldRender?: boolean): void;
41
+ render(): React.JSX.Element;
42
+ context: unknown;
43
+ setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<{}>) => {} | Pick<{}, K>) | Pick<{}, K>, callback?: () => void): void;
44
+ forceUpdate(callback?: () => void): void;
45
+ readonly props: Readonly<{}>;
46
+ state: Readonly<{}>;
47
+ refs: {
48
+ [key: string]: React.ReactInstance;
49
+ };
50
+ shouldComponentUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): boolean;
51
+ componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
52
+ getSnapshotBeforeUpdate?(prevProps: Readonly<{}>, prevState: Readonly<{}>): any;
53
+ componentWillMount?(): void;
54
+ UNSAFE_componentWillMount?(): void;
55
+ componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
56
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<{}>, nextContext: any): void;
57
+ componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
58
+ UNSAFE_componentWillUpdate?(nextProps: Readonly<{}>, nextState: Readonly<{}>, nextContext: any): void;
59
+ };
60
+ contextType?: React.Context<any>;
61
+ };
62
+ export {};
@@ -0,0 +1,87 @@
1
+ import { _ as _assert_this_initialized } from "@swc/helpers/_/_assert_this_initialized";
2
+ import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
3
+ import { _ as _create_class } from "@swc/helpers/_/_create_class";
4
+ import { _ as _define_property } from "@swc/helpers/_/_define_property";
5
+ import { _ as _inherits } from "@swc/helpers/_/_inherits";
6
+ import { _ as _create_super } from "@swc/helpers/_/_create_super";
7
+ import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime";
8
+ import * as React from "react";
9
+ var Component = /*#__PURE__*/ function(_React_Component) {
10
+ "use strict";
11
+ _inherits(Component, _React_Component);
12
+ var _super = _create_super(Component);
13
+ function Component() {
14
+ _class_call_check(this, Component);
15
+ return _super.apply(this, arguments);
16
+ }
17
+ _create_class(Component, [
18
+ {
19
+ key: "render",
20
+ value: function render() {
21
+ var containerRef = this.props.containerRef;
22
+ return /*#__PURE__*/ _jsx("div", {
23
+ ref: containerRef
24
+ });
25
+ }
26
+ }
27
+ ]);
28
+ return Component;
29
+ }(React.Component);
30
+ export var FallBack = function(param) {
31
+ var Original = param.Original, remoteReactDOM = param.remoteReactDOM, remoteReact = param.remoteReact;
32
+ var ReactDOM = remoteReactDOM();
33
+ var _$React = remoteReact();
34
+ var WrappedComponent = /*#__PURE__*/ function(_React_Component) {
35
+ "use strict";
36
+ _inherits(WrappedComponent, _React_Component);
37
+ var _super = _create_super(WrappedComponent);
38
+ function WrappedComponent() {
39
+ _class_call_check(this, WrappedComponent);
40
+ var _this;
41
+ _this = _super.apply(this, arguments);
42
+ _define_property(_assert_this_initialized(_this), "containerRef", _$React.createRef());
43
+ return _this;
44
+ }
45
+ _create_class(WrappedComponent, [
46
+ {
47
+ key: "componentDidMount",
48
+ value: function componentDidMount() {
49
+ this.mountOriginalComponent(true);
50
+ }
51
+ },
52
+ {
53
+ key: "componentDidUpdate",
54
+ value: function componentDidUpdate() {
55
+ this.mountOriginalComponent();
56
+ }
57
+ },
58
+ {
59
+ key: "componentWillUnmount",
60
+ value: function componentWillUnmount() {
61
+ if (this.containerRef.current) {
62
+ ReactDOM.unmountComponentAtNode(this.containerRef.current);
63
+ }
64
+ }
65
+ },
66
+ {
67
+ key: "mountOriginalComponent",
68
+ value: function mountOriginalComponent() {
69
+ var shouldRender = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : false;
70
+ var element = _$React.createElement(Original, this.props);
71
+ var renderMethod = shouldRender ? ReactDOM.render : ReactDOM.hydrate;
72
+ renderMethod(element, this.containerRef.current);
73
+ }
74
+ },
75
+ {
76
+ key: "render",
77
+ value: function render() {
78
+ return /*#__PURE__*/ _jsx(Component, {
79
+ containerRef: this.containerRef
80
+ });
81
+ }
82
+ }
83
+ ]);
84
+ return WrappedComponent;
85
+ }(_$React.Component);
86
+ return WrappedComponent;
87
+ };
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ interface RemoteModuleOptions {
3
+ module: string;
4
+ scope: string;
5
+ runtime?: {
6
+ react: typeof import('react');
7
+ reactDOM: typeof import('react-dom');
8
+ };
9
+ publicPath?: string;
10
+ LoadingComponent?: React.ReactNode;
11
+ }
12
+ export declare const RemoteModule: ({ module, scope, runtime, publicPath, LoadingComponent, }: RemoteModuleOptions) => string | number | true | Iterable<React.ReactNode> | React.JSX.Element;
13
+ export {};
@@ -0,0 +1,107 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
+ import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
3
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
4
+ import { jsx as _jsx } from "@ice/jsx-runtime/jsx-runtime";
5
+ import { loadRemote } from "@module-federation/runtime";
6
+ import * as React from "react";
7
+ import { useEffect, useState } from "react";
8
+ import { FallBack } from "./FallBack";
9
+ import { setFederatedModulePublicPath } from "./set-public-path";
10
+ function useDynamicImport(param) {
11
+ var module = param.module, scope = param.scope;
12
+ var _useState = _sliced_to_array(useState(null), 2), component = _useState[0], setComponent = _useState[1];
13
+ useEffect(function() {
14
+ if (!module || !scope) return;
15
+ var loadComponent = function() {
16
+ var _ref = _async_to_generator(function() {
17
+ var res, error;
18
+ return _ts_generator(this, function(_state) {
19
+ switch(_state.label){
20
+ case 0:
21
+ _state.trys.push([
22
+ 0,
23
+ 2,
24
+ ,
25
+ 3
26
+ ]);
27
+ return [
28
+ 4,
29
+ loadRemote("".concat(scope, "/").concat(module))
30
+ ];
31
+ case 1:
32
+ res = _state.sent();
33
+ setComponent(res);
34
+ return [
35
+ 3,
36
+ 3
37
+ ];
38
+ case 2:
39
+ error = _state.sent();
40
+ console.error("Error loading remote module ".concat(scope, "/").concat(module, ":"), error);
41
+ return [
42
+ 3,
43
+ 3
44
+ ];
45
+ case 3:
46
+ return [
47
+ 2
48
+ ];
49
+ }
50
+ });
51
+ });
52
+ return function loadComponent() {
53
+ return _ref.apply(this, arguments);
54
+ };
55
+ }();
56
+ loadComponent();
57
+ }, [
58
+ module,
59
+ scope
60
+ ]);
61
+ return component;
62
+ }
63
+ export var RemoteModule = function(param) {
64
+ var module = param.module, scope = param.scope, runtime = param.runtime, publicPath = param.publicPath, LoadingComponent = param.LoadingComponent;
65
+ var _remoteModule;
66
+ if (publicPath) {
67
+ setFederatedModulePublicPath(scope, publicPath);
68
+ }
69
+ var remoteModule = useDynamicImport({
70
+ module: module,
71
+ scope: scope
72
+ });
73
+ var Component = null;
74
+ if ((_remoteModule = remoteModule) === null || _remoteModule === void 0 ? void 0 : _remoteModule.default) {
75
+ if (runtime) {
76
+ var react = runtime.react, reactDOM = runtime.reactDOM;
77
+ var w = FallBack({
78
+ Original: remoteModule.default,
79
+ remoteReact: function() {
80
+ return react;
81
+ },
82
+ remoteReactDOM: function() {
83
+ return reactDOM;
84
+ }
85
+ });
86
+ Component = w;
87
+ } else {
88
+ Component = /*#__PURE__*/ React.lazy(function() {
89
+ return Promise.resolve({
90
+ default: remoteModule.default
91
+ });
92
+ });
93
+ }
94
+ } else {
95
+ Component = remoteModule;
96
+ }
97
+ var Loading = LoadingComponent || /*#__PURE__*/ _jsx("div", {
98
+ children: "Loading..."
99
+ });
100
+ if (Component) {
101
+ return /*#__PURE__*/ _jsx(React.Suspense, {
102
+ fallback: Loading,
103
+ children: /*#__PURE__*/ _jsx(Component, {})
104
+ });
105
+ }
106
+ return Loading;
107
+ };
package/esm/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { ExtendedUserOptions } from './types';
2
+ export { loadRemote, registerPlugins } from '@module-federation/runtime';
3
+ export * from './FallBack';
4
+ export * from './RemoteModule';
5
+ export declare function init(options: ExtendedUserOptions): void;
package/esm/index.js ADDED
@@ -0,0 +1,11 @@
1
+ import { registerPlugins, init as mfInit } from "@module-federation/runtime";
2
+ import { runtimePlugin } from "./runtime-plugin";
3
+ export { loadRemote, registerPlugins } from "@module-federation/runtime";
4
+ export * from "./FallBack";
5
+ export * from "./RemoteModule";
6
+ export function init(options) {
7
+ mfInit(options);
8
+ registerPlugins([
9
+ runtimePlugin()
10
+ ]);
11
+ }
@@ -0,0 +1,27 @@
1
+ import type { ExtraInfo, ExtendedUserOptions } from './types';
2
+ export interface RemoteModuleInfo {
3
+ key: string;
4
+ name: string;
5
+ entry: string;
6
+ hostName: string;
7
+ version?: string;
8
+ extraInfo?: ExtraInfo;
9
+ }
10
+ export interface HostRemoteInfo {
11
+ keys: Set<string>;
12
+ nameKeyMap: Map<string, string>;
13
+ conflictingModules: Set<string>;
14
+ }
15
+ declare global {
16
+ interface Window {
17
+ __MF_GLOBAL_STORE__: {
18
+ remotes: Map<string, RemoteModuleInfo>;
19
+ hostRemotes: Map<string, HostRemoteInfo>;
20
+ };
21
+ }
22
+ }
23
+ export declare function initGlobalStore(options: ExtendedUserOptions): void;
24
+ export declare function generateRemoteKey(name: string, entry: string): string;
25
+ export declare function getRemoteInfoFromStore(hostName: string, remoteName: string): RemoteModuleInfo | undefined;
26
+ export declare function hasConflict(hostName: string, remoteName: string): boolean;
27
+ export declare function getExtraInfo(hostName: string, remoteName: string): ExtraInfo;
@@ -0,0 +1,84 @@
1
+ import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
2
+ export function initGlobalStore(options) {
3
+ if (!window.__MF_GLOBAL_STORE__) {
4
+ window.__MF_GLOBAL_STORE__ = {
5
+ remotes: new Map(),
6
+ hostRemotes: new Map()
7
+ };
8
+ }
9
+ var store = window.__MF_GLOBAL_STORE__;
10
+ var hostInfo = {
11
+ keys: new Set(),
12
+ nameKeyMap: new Map(),
13
+ conflictingModules: new Set()
14
+ };
15
+ // 更新每个 remote 模块的信息
16
+ options.remotes.forEach(function(remote) {
17
+ if (!remote.name) return;
18
+ var entry = remote.entry;
19
+ var remoteKey = generateRemoteKey(remote.name, entry);
20
+ var newInfo = {
21
+ key: remoteKey,
22
+ name: remote.name,
23
+ entry: entry,
24
+ hostName: options.name,
25
+ extraInfo: remote.extraInfo
26
+ };
27
+ // 记录这个 host 使用的 remote key 和 name 到 key 的映射
28
+ hostInfo.keys.add(remoteKey);
29
+ hostInfo.nameKeyMap.set(remote.name, remoteKey);
30
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
31
+ try {
32
+ // 检查是否与现有模块冲突
33
+ for(var _iterator = store.remotes.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
34
+ var _step_value = _sliced_to_array(_step.value, 2), info = _step_value[1];
35
+ if (info.name === remote.name && info.entry !== entry) {
36
+ console.warn('[Module Federation] Remote module "'.concat(remote.name, '" has multiple versions:'), '\nHost "'.concat(info.hostName, '": ').concat(info.entry), '\nHost "'.concat(options.name, '": ').concat(entry));
37
+ // 在 host 环境中标记该模块存在冲突
38
+ hostInfo.conflictingModules.add(remote.name);
39
+ }
40
+ }
41
+ } catch (err) {
42
+ _didIteratorError = true;
43
+ _iteratorError = err;
44
+ } finally{
45
+ try {
46
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
47
+ _iterator.return();
48
+ }
49
+ } finally{
50
+ if (_didIteratorError) {
51
+ throw _iteratorError;
52
+ }
53
+ }
54
+ }
55
+ store.remotes.set(remoteKey, newInfo);
56
+ });
57
+ // 更新 host 的 remote 信息
58
+ store.hostRemotes.set(options.name, hostInfo);
59
+ }
60
+ // 生成 remote 模块的唯一标识
61
+ export function generateRemoteKey(name, entry) {
62
+ return "".concat(name, "@").concat(entry);
63
+ }
64
+ export function getRemoteInfoFromStore(hostName, remoteName) {
65
+ var store = window.__MF_GLOBAL_STORE__;
66
+ var hostInfo = store.hostRemotes.get(hostName);
67
+ if (!hostInfo) return undefined;
68
+ var remoteKey = hostInfo.nameKeyMap.get(remoteName);
69
+ if (!remoteKey) return undefined;
70
+ return store.remotes.get(remoteKey);
71
+ }
72
+ // 检查指定的 remote 模块在当前 host 环境中是否存在冲突
73
+ export function hasConflict(hostName, remoteName) {
74
+ var _hostInfo;
75
+ var store = window.__MF_GLOBAL_STORE__;
76
+ var hostInfo = store.hostRemotes.get(hostName);
77
+ var _hostInfo_conflictingModules_has;
78
+ return (_hostInfo_conflictingModules_has = (_hostInfo = hostInfo) === null || _hostInfo === void 0 ? void 0 : _hostInfo.conflictingModules.has(remoteName)) !== null && _hostInfo_conflictingModules_has !== void 0 ? _hostInfo_conflictingModules_has : false;
79
+ }
80
+ export function getExtraInfo(hostName, remoteName) {
81
+ var _remoteInfo;
82
+ var remoteInfo = getRemoteInfoFromStore(hostName, remoteName);
83
+ return (_remoteInfo = remoteInfo) === null || _remoteInfo === void 0 ? void 0 : _remoteInfo.extraInfo;
84
+ }
@@ -0,0 +1,2 @@
1
+ import { type FederationRuntimePlugin } from '@module-federation/runtime';
2
+ export declare const runtimePlugin: () => FederationRuntimePlugin;
@@ -0,0 +1,215 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
+ import * as React from "react";
4
+ import { getExtraInfo, getRemoteInfoFromStore, hasConflict } from "./mf-global-store";
5
+ var loadRemotePackagedReactAndRender = function() {
6
+ var _ref = _async_to_generator(function(args) {
7
+ var _args_origin_options_shared_reactdom_, _args_origin_options_shared_reactdom, _args_origin_options_shared, _args_origin_options, _remoteInstance_options_shared_reactdom_, _remoteInstance_options_shared_reactdom, _remoteInstance_options_shared, _remoteInstance_options, hostVersion, remoteInstance, remoteVersion, _sharedOptions_find, remoteReactDOM, _sharedOptions_find1, remoteReact, res;
8
+ return _ts_generator(this, function(_state) {
9
+ switch(_state.label){
10
+ case 0:
11
+ hostVersion = ((_args_origin_options = args.origin.options) === null || _args_origin_options === void 0 ? void 0 : (_args_origin_options_shared = _args_origin_options.shared) === null || _args_origin_options_shared === void 0 ? void 0 : (_args_origin_options_shared_reactdom = _args_origin_options_shared["react-dom"]) === null || _args_origin_options_shared_reactdom === void 0 ? void 0 : (_args_origin_options_shared_reactdom_ = _args_origin_options_shared_reactdom[0]) === null || _args_origin_options_shared_reactdom_ === void 0 ? void 0 : _args_origin_options_shared_reactdom_.version) || React.version;
12
+ remoteInstance = __FEDERATION__.__INSTANCES__.find(// @ts-expect-error wrong type
13
+ function(instance) {
14
+ return instance.name === args.remote.name;
15
+ });
16
+ remoteVersion = remoteInstance ? (_remoteInstance_options = remoteInstance.options) === null || _remoteInstance_options === void 0 ? void 0 : (_remoteInstance_options_shared = _remoteInstance_options.shared) === null || _remoteInstance_options_shared === void 0 ? void 0 : (_remoteInstance_options_shared_reactdom = _remoteInstance_options_shared["react-dom"]) === null || _remoteInstance_options_shared_reactdom === void 0 ? void 0 : (_remoteInstance_options_shared_reactdom_ = _remoteInstance_options_shared_reactdom[0]) === null || _remoteInstance_options_shared_reactdom_ === void 0 ? void 0 : _remoteInstance_options_shared_reactdom_.version : false;
17
+ if (!(remoteVersion && hostVersion && remoteVersion !== hostVersion)) return [
18
+ 3,
19
+ 4
20
+ ];
21
+ return [
22
+ 4,
23
+ remoteInstance.loadShare("react-dom", {
24
+ resolver: function(sharedOptions) {
25
+ return (_sharedOptions_find = sharedOptions.find(function(i) {
26
+ return i.version === remoteVersion;
27
+ })) !== null && _sharedOptions_find !== void 0 ? _sharedOptions_find : sharedOptions[0];
28
+ }
29
+ })
30
+ ];
31
+ case 1:
32
+ remoteReactDOM = _state.sent();
33
+ return [
34
+ 4,
35
+ remoteInstance.loadShare("react", {
36
+ resolver: function(sharedOptions) {
37
+ return (_sharedOptions_find1 = sharedOptions.find(function(i) {
38
+ return i.version === remoteVersion;
39
+ })) !== null && _sharedOptions_find1 !== void 0 ? _sharedOptions_find1 : sharedOptions[0];
40
+ }
41
+ })
42
+ ];
43
+ case 2:
44
+ remoteReact = _state.sent();
45
+ if (!remoteReact || !remoteReactDOM) {
46
+ return [
47
+ 2,
48
+ null
49
+ ];
50
+ }
51
+ return [
52
+ 4,
53
+ import("./FallBack")
54
+ ];
55
+ case 3:
56
+ res = _state.sent().FallBack;
57
+ return [
58
+ 2,
59
+ function() {
60
+ return res({
61
+ Original: args.exposeModule.default,
62
+ remoteVersion: function() {
63
+ return remoteVersion;
64
+ },
65
+ hostVersion: function() {
66
+ return hostVersion;
67
+ },
68
+ remoteReactDOM: remoteReactDOM,
69
+ remoteReact: remoteReact
70
+ });
71
+ }
72
+ ];
73
+ case 4:
74
+ return [
75
+ 2,
76
+ null
77
+ ];
78
+ }
79
+ });
80
+ });
81
+ return function loadRemotePackagedReactAndRender(args) {
82
+ return _ref.apply(this, arguments);
83
+ };
84
+ }();
85
+ export var runtimePlugin = function() {
86
+ return {
87
+ name: "ice-runtime-plugin",
88
+ afterResolve: function afterResolve(args) {
89
+ var _extraInfo;
90
+ var hostName = args.options.name;
91
+ var remoteName = args.remote.name;
92
+ var extraInfo = getExtraInfo(hostName, remoteName);
93
+ if ((_extraInfo = extraInfo) === null || _extraInfo === void 0 ? void 0 : _extraInfo.legacy) {
94
+ if (args.expose.startsWith("./")) {
95
+ args.expose = args.expose.slice(2);
96
+ }
97
+ }
98
+ return args;
99
+ },
100
+ onLoad: function onLoad(args) {
101
+ return _async_to_generator(function() {
102
+ var _args_origin_options_shared_reactdom_, _args_origin_options_shared_reactdom, _args_origin_options_shared, _args_origin_options, _extraInfo, hostName, remoteName, hostVersion, extraInfo, externalReact, externalReactDOM, remoteReact, remoteReactDOM, res, fallBackRender;
103
+ return _ts_generator(this, function(_state) {
104
+ switch(_state.label){
105
+ case 0:
106
+ hostName = args.origin.name;
107
+ remoteName = args.remote.name;
108
+ hostVersion = ((_args_origin_options = args.origin.options) === null || _args_origin_options === void 0 ? void 0 : (_args_origin_options_shared = _args_origin_options.shared) === null || _args_origin_options_shared === void 0 ? void 0 : (_args_origin_options_shared_reactdom = _args_origin_options_shared["react-dom"]) === null || _args_origin_options_shared_reactdom === void 0 ? void 0 : (_args_origin_options_shared_reactdom_ = _args_origin_options_shared_reactdom[0]) === null || _args_origin_options_shared_reactdom_ === void 0 ? void 0 : _args_origin_options_shared_reactdom_.version) || React.version;
109
+ extraInfo = getExtraInfo(hostName, remoteName);
110
+ if (!((_extraInfo = extraInfo) === null || _extraInfo === void 0 ? void 0 : _extraInfo.external)) return [
111
+ 3,
112
+ 2
113
+ ];
114
+ externalReact = extraInfo.external["react"];
115
+ externalReactDOM = extraInfo.external["react-dom"];
116
+ if (!(externalReact && externalReactDOM)) return [
117
+ 3,
118
+ 2
119
+ ];
120
+ remoteReact = function() {
121
+ return window[externalReact];
122
+ };
123
+ remoteReactDOM = function() {
124
+ return window[externalReactDOM];
125
+ };
126
+ if (remoteReactDOM().version === hostVersion) {
127
+ console.log("[runtime Plugin onLoad] use same external react");
128
+ return [
129
+ 2,
130
+ args
131
+ ];
132
+ }
133
+ return [
134
+ 4,
135
+ import("./FallBack")
136
+ ];
137
+ case 1:
138
+ res = _state.sent().FallBack;
139
+ return [
140
+ 2,
141
+ function() {
142
+ return res({
143
+ Original: args.exposeModule.default,
144
+ remoteReactDOM: remoteReactDOM,
145
+ remoteReact: remoteReact
146
+ });
147
+ }
148
+ ];
149
+ case 2:
150
+ return [
151
+ 4,
152
+ loadRemotePackagedReactAndRender(args)
153
+ ];
154
+ case 3:
155
+ fallBackRender = _state.sent();
156
+ if (fallBackRender) {
157
+ return [
158
+ 2,
159
+ fallBackRender
160
+ ];
161
+ }
162
+ return [
163
+ 2,
164
+ args
165
+ ];
166
+ }
167
+ });
168
+ })();
169
+ },
170
+ beforeRequest: function beforeRequest(args) {
171
+ return _async_to_generator(function() {
172
+ var remoteName, hostName, newRemoteInfo, requestRemote, hostInstance;
173
+ return _ts_generator(this, function(_state) {
174
+ remoteName = args.id.split("/")[0];
175
+ hostName = args.options.name;
176
+ if (!hasConflict(hostName, remoteName)) {
177
+ return [
178
+ 2,
179
+ args
180
+ ];
181
+ }
182
+ newRemoteInfo = getRemoteInfoFromStore(hostName, remoteName);
183
+ if (!newRemoteInfo) {
184
+ return [
185
+ 2,
186
+ args
187
+ ];
188
+ }
189
+ requestRemote = args.options.remotes.find(function(remote) {
190
+ return remote.name === remoteName;
191
+ });
192
+ if (requestRemote) {
193
+ requestRemote.entry = newRemoteInfo.entry;
194
+ }
195
+ hostInstance = __FEDERATION__.__INSTANCES__.find(function(instance) {
196
+ return instance.name === hostName;
197
+ });
198
+ if (hostInstance) {
199
+ hostInstance.moduleCache.delete(remoteName);
200
+ hostInstance.options.remotes.find(function(remote) {
201
+ return remote.name === remoteName;
202
+ }).entry = newRemoteInfo.entry;
203
+ }
204
+ args.origin.moduleCache.delete(remoteName);
205
+ // @ts-expect-error for global module
206
+ window[remoteName] = null;
207
+ return [
208
+ 2,
209
+ args
210
+ ];
211
+ });
212
+ })();
213
+ }
214
+ };
215
+ };
@@ -0,0 +1,2 @@
1
+ export declare const ensureSlash: (input: string, needSlash: boolean, position: 'tail' | 'head') => string;
2
+ export declare const setFederatedModulePublicPath: (scope: string, publicPath: string) => void;
@@ -0,0 +1,28 @@
1
+ export var ensureSlash = function(input, needSlash, position) {
2
+ if (input == null) return input;
3
+ if (position === "head") {
4
+ var startWithSlash = input.startsWith("/");
5
+ if (startWithSlash && !needSlash) {
6
+ return input.slice(1);
7
+ } else if (!startWithSlash && needSlash) {
8
+ return "/".concat(input);
9
+ }
10
+ return input;
11
+ } else if (position === "tail") {
12
+ var endsWithSlash = input.endsWith("/");
13
+ if (endsWithSlash && !needSlash) {
14
+ return input.substr(0, input.length - 1);
15
+ } else if (!endsWithSlash && needSlash) {
16
+ return "".concat(input, "/");
17
+ } else {
18
+ return input;
19
+ }
20
+ } else {
21
+ return input;
22
+ }
23
+ };
24
+ export var setFederatedModulePublicPath = function(scope, publicPath) {
25
+ var publicPathReference = "".concat(scope, "_public_path");
26
+ // @ts-expect-error for global public path
27
+ window[publicPathReference] = ensureSlash(publicPath, true, "tail");
28
+ };
package/esm/types.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { UserOptions } from '@module-federation/runtime-core';
2
+ import type { Remote } from '@module-federation/runtime-core/dist/src/types';
3
+ export interface ExtraInfo {
4
+ external?: Record<string, string>;
5
+ legacy?: boolean;
6
+ }
7
+ export type ExtendedRemote = Remote & {
8
+ extraInfo?: ExtraInfo;
9
+ };
10
+ export interface ExtendedUserOptions extends Omit<UserOptions, 'remotes'> {
11
+ remotes: ExtendedRemote[];
12
+ }
package/esm/types.js ADDED
@@ -0,0 +1 @@
1
+ export { };
@@ -0,0 +1 @@
1
+ /// <reference types="@ice/pkg/types" />
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@ice/mf-runtime",
3
+ "version": "0.0.1",
4
+ "description": "组件功能描述",
5
+ "files": [
6
+ "esm",
7
+ "es2017",
8
+ "cjs",
9
+ "dist"
10
+ ],
11
+ "main": "esm/index.js",
12
+ "module": "esm/index.js",
13
+ "types": "esm/index.d.ts",
14
+ "exports": {
15
+ ".": {
16
+ "es2017": {
17
+ "types": "./es2017/index.d.ts",
18
+ "default": "./es2017/index.js"
19
+ },
20
+ "default": {
21
+ "types": "./esm/index.d.ts",
22
+ "default": "./esm/index.js"
23
+ }
24
+ },
25
+ "./*": "./*"
26
+ },
27
+ "sideEffects": [
28
+ "dist/*",
29
+ "*.scss",
30
+ "*.less",
31
+ "*.css"
32
+ ],
33
+ "scripts": {
34
+ "start": "ice-pkg start",
35
+ "build": "ice-pkg build",
36
+ "prepublishOnly": "npm run build",
37
+ "eslint": "eslint --cache --ext .js,.jsx,.ts,.tsx ./",
38
+ "eslint:fix": "npm run eslint -- --fix",
39
+ "stylelint": "stylelint \"**/*.{css,scss,less}\"",
40
+ "lint": "npm run eslint && npm run stylelint"
41
+ },
42
+ "keywords": [
43
+ "ice",
44
+ "react",
45
+ "component"
46
+ ],
47
+ "dependencies": {
48
+ "@ice/jsx-runtime": "^0.2.0",
49
+ "@module-federation/runtime": "^0.11.2",
50
+ "@module-federation/runtime-core": "^0.11.2",
51
+ "@swc/helpers": "^0.5.1"
52
+ },
53
+ "devDependencies": {
54
+ "@ali/pkg-plugin-dev": "^1.0.0",
55
+ "@ali/pkg-plugin-dev-client": "^1.0.0",
56
+ "@applint/spec": "^1.2.3",
57
+ "@ice/pkg": "^1.0.0",
58
+ "@ice/runtime": "^1.0.0",
59
+ "@types/react": "^18.0.0",
60
+ "@types/react-dom": "^18.0.0",
61
+ "eslint": "^8.0.0",
62
+ "react": "^18.0.0",
63
+ "react-dom": "^18.0.0",
64
+ "stylelint": "^15.0.0"
65
+ },
66
+ "publishConfig": {
67
+ "access": "public"
68
+ },
69
+ "peerDependencies": {
70
+ "react": "^16 || ^17 || ^18"
71
+ },
72
+ "license": "MIT"
73
+ }