Modern.js
该插件为 Modern.js 提供 Module Federation 配套功能
支持
- modern.js ^2.56.1
- 包含服务器端渲染(SSR)
强烈推荐参考这个应用,它充分利用了最佳功能:
module-federation 示例
快速开始
安装
你可以通过如下的命令安装插件:
npm add @module-federation/modern-js --save
应用插件
在 modern.config.ts
的 plugins
中应用此插件:
modern.config.ts
import { appTools, defineConfig } from '@modern-js/app-tools';
import { moduleFederationPlugin } from '@module-federation/modern-js';
export default defineConfig({
dev: {
port: 3005,
},
runtime: {
router: true,
},
// moduleFederationPlugin 是 modern.js 的插件,可以对构建/运行时做一定的修改
plugins: [appTools(), moduleFederationPlugin()],
});
随后创建 module-federation.config.ts
文件,并写入需要的配置:
module-federation.config.ts
import { createModuleFederationConfig } from '@module-federation/modern-js';
export default createModuleFederationConfig({
name: 'host',
remotes: {
remote: 'remote@http://localhost:3006/mf-manifest.json',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
});
引用类型
在 modern-app-env.d.ts
文件增加 /// <reference types='@module-federation/modern-js/types' />
以获取运行时 @@modern-js/runtime/mf
类型支持。
modern-app-env.d.ts
+ /// <reference types='@module-federation/modern-js/types' />
在 tsconfig.json
添加 paths
以获取生产者的类型:
{
"compilerOptions": {
"paths": {
"*": ["./@mf-types/*"]
}
}
}
服务端渲染(SSR)
注意
为更好的性能体验,Module Federation X Modern.js SSR 仅支持 stream SSR 。
在 SSR 场景与 CSR 场景中使用 Module Federation 没有任何区别,开发者保持按照原有的开发行为即可。
但为了更好地使用体验,我们提供了配套的函数/组件来帮助开发者更好的使用 Module Federation。
createRemoteSSRComponent
Type declaration
declare function createRemoteSSRComponent(
props: CreateRemoteSSRComponentOptions
): (props: ComponentType) => React.JSX.Element;
type CreateRemoteSSRComponentOptions = {
loader: () => Promise<T>;
loading: React.ReactNode;
fallback: ErrorBoundaryPropsWithComponent['FallbackComponent'];
export?: E;
};
type ComponentType = T[E] extends (...args: any) => any
? Parameters<T[E]>[0] extends undefined
? Record<string, never>
: Parameters<T[E]>[0]
: Record<string, never>;
该函数在加载组件同时,还会帮助注入相应的样式标签/脚本 ,此行为可以帮助避免流式渲染带来的 CSS 闪烁问题以及加速 PID (首屏可交互时间)。
示例
import React, { FC, memo, useEffect } from 'react';
import { registerRemotes, createRemoteSSRComponent } from '@modern-js/runtime/mf';
// 在构建插件声明过的 remote 可以直接在顶层 import
import RemoteComp from 'remote/Image';
const RemoteSSRComponent = createRemoteSSRComponent({
// 在构建插件声明过的 remote 也可以使用此函数加载:loader: () => import('remote/Image'),
loader: () => loadRemote('dynamic_remote/Image'),
loading: <div>loading...</div>,
fallback: ({ error }) => {
if (error instanceof Error && error.message.includes('not exist')) {
return <div>fallback - not existed id</div>;
}
return <div>fallback</div>;
},
});
const Product: FC = () => {
registerRemotes([
{
name: 'dynamic_remote',
entry: 'http://localhost:3008/mf-manifest.json',
},
]);
const fallback = (err: Error) => {
if (err.message.includes('does not exist in container')) {
return <div>404</div>;
}
throw err;
};
return <>
<RemoteSSRComponent />
<RemoteComp />
</>;
};
export default Product;
loading
- 类型:
React.ReactNode
- 是否必填:是
- 默认值:
undefined
设置模块载入状态。
fallback
- 类型:
(({ error }: { error: Error}) => React.ReactElement)
- 是否必填:是
- 默认值:
undefined
当组件加载或渲染失败时,所渲染的容错组件。
注意:当渲染失败的时候,该组件仅在客户端渲染此 容错组件。
配置
ssr
- 类型:
false
- 是否必填:否
- 默认值:
undefined
@module-federation/modern-js
会根据 modern.js config 中的 server.ssr
来自动添加 SSR 相关的构建预设。
如果当前项目仅需要在 CSR 加载 MF ,那么可以设置 ssr: false
来帮助渐进式迁移。
import { appTools, defineConfig } from '@modern-js/app-tools';
import { moduleFederationPlugin } from '@module-federation/modern-js';
// https://modernjs.dev/en/configure/app/usage
export default defineConfig({
dev: {
port: 3050,
},
runtime: {
router: true,
},
server: {
ssr: {
mode: 'stream',
},
},
plugins: [
appTools(),
moduleFederationPlugin({ ssr: false })
],
});