diff --git a/umijs-react-ts-demo/app1/.editorconfig b/umijs-react-ts-demo/app1/.editorconfig
new file mode 100755
index 00000000000..7e3649acc2c
--- /dev/null
+++ b/umijs-react-ts-demo/app1/.editorconfig
@@ -0,0 +1,16 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
+
+[Makefile]
+indent_style = tab
diff --git a/umijs-react-ts-demo/app1/.gitignore b/umijs-react-ts-demo/app1/.gitignore
new file mode 100644
index 00000000000..bee1cf61ce7
--- /dev/null
+++ b/umijs-react-ts-demo/app1/.gitignore
@@ -0,0 +1,20 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/npm-debug.log*
+/yarn-error.log
+/yarn.lock
+/package-lock.json
+
+# production
+/dist
+
+# misc
+.DS_Store
+
+# umi
+/src/.umi
+/src/.umi-production
+/src/.umi-test
+/.env.local
diff --git a/umijs-react-ts-demo/app1/.prettierignore b/umijs-react-ts-demo/app1/.prettierignore
new file mode 100644
index 00000000000..0d4222f5443
--- /dev/null
+++ b/umijs-react-ts-demo/app1/.prettierignore
@@ -0,0 +1,8 @@
+**/*.md
+**/*.svg
+**/*.ejs
+**/*.html
+package.json
+.umi
+.umi-production
+.umi-test
diff --git a/umijs-react-ts-demo/app1/.umirc.ts b/umijs-react-ts-demo/app1/.umirc.ts
new file mode 100644
index 00000000000..f99dcb1c16a
--- /dev/null
+++ b/umijs-react-ts-demo/app1/.umirc.ts
@@ -0,0 +1,64 @@
+import { defineConfig } from 'umi';
+import { join } from 'path';
+
+const pkg = require('../package.json');
+const deps = pkg.dependencies;
+
+function webpackDeepPathImportWorkaround() {
+  const mod = require('module');
+  const resolveFilename = mod._resolveFilename;
+
+  mod._resolveFilename = function (request: string, parent: any, isMain: boolean, options: any) {
+    let newRequest = request;
+
+    if (/\/@umijs\/deps\/compiled\/(lib|schemas)\//.test(request)) {
+      newRequest = request.replace(
+        /.*@umijs\/deps\/compiled\/(lib|schemas)\//,
+        join(__dirname, './node_modules/webpack/$1', './'),
+      );
+    }
+
+    return resolveFilename.call(mod, newRequest, parent, isMain, options);
+  };
+}
+
+export default defineConfig({
+  nodeModulesTransform: {
+    type: 'none',
+  },
+  routes: [
+    { path: '/', component: '@/pages/index' },
+  ],
+  fastRefresh: {},
+  webpack5: {},
+  chainWebpack: (config, { webpack }: any) => {
+    // reference https://github.com/umijs/umi/issues/10583
+    webpackDeepPathImportWorkaround();
+
+    // error: Not found module './src/pages/index'
+    // const { ModuleFederationPlugin } = require('@module-federation/enhanced');
+
+    config.plugin('mf').use(webpack.container.ModuleFederationPlugin, [{
+      name: 'app1',
+      filename: 'remoteEntry.js',
+      exposes: {
+        './Header': './src/pages/index',
+      },
+      shared: {
+        ...deps,
+        react: {
+          eager: true,
+          singleton: true,
+          requiredVersion: '^17.0.0',
+          version: '0',
+        },
+        'react-dom': {
+          eager: true,
+          singleton: true,
+          requiredVersion: '^17.0.0',
+          version: '0',
+        },
+      },
+    }])
+  }
+});
diff --git a/umijs-react-ts-demo/app1/README.md b/umijs-react-ts-demo/app1/README.md
new file mode 100644
index 00000000000..07afeb7fd6d
--- /dev/null
+++ b/umijs-react-ts-demo/app1/README.md
@@ -0,0 +1,15 @@
+# umi project
+
+## Getting Started
+
+Install dependencies,
+
+```bash
+$ yarn
+```
+
+Start the dev server,
+
+```bash
+$ yarn start
+```
diff --git a/umijs-react-ts-demo/app1/mock/.gitkeep b/umijs-react-ts-demo/app1/mock/.gitkeep
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/umijs-react-ts-demo/app1/package.json b/umijs-react-ts-demo/app1/package.json
new file mode 100644
index 00000000000..f586e45dec0
--- /dev/null
+++ b/umijs-react-ts-demo/app1/package.json
@@ -0,0 +1,41 @@
+{
+  "private": true,
+  "scripts": {
+    "start": "umi dev",
+    "build": "umi build",
+    "postinstall": "umi generate tmp",
+    "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'",
+    "test": "umi-test",
+    "test:coverage": "umi-test --coverage"
+  },
+  "gitHooks": {
+    "pre-commit": "lint-staged"
+  },
+  "lint-staged": {
+    "*.{js,jsx,less,md,json}": [
+      "prettier --write"
+    ],
+    "*.ts?(x)": [
+      "prettier --parser=typescript --write"
+    ]
+  },
+  "dependencies": {
+    "@ant-design/pro-layout": "^6.5.0",
+    "react": "17.x",
+    "react-dom": "17.x",
+    "umi": "^3.5.41"
+  },
+  "devDependencies": {
+    "@module-federation/enhanced": "^0.0.10",
+    "@module-federation/runtime": "^0.0.10",
+    "@types/react": "^17.0.0",
+    "@types/react-dom": "^17.0.0",
+    "@umijs/preset-react": "1.x",
+    "@umijs/test": "^3.5.41",
+    "lint-staged": "^10.0.7",
+    "prettier": "^2.2.0",
+    "typescript": "^4.1.2",
+    "webpack": "5.89.0",
+    "yorkie": "^2.0.0"
+  }
+}
diff --git a/umijs-react-ts-demo/app1/src/pages/index.less b/umijs-react-ts-demo/app1/src/pages/index.less
new file mode 100644
index 00000000000..586302bfc88
--- /dev/null
+++ b/umijs-react-ts-demo/app1/src/pages/index.less
@@ -0,0 +1,3 @@
+.title {
+  background: rgb(121, 242, 157);
+}
diff --git a/umijs-react-ts-demo/app1/src/pages/index.tsx b/umijs-react-ts-demo/app1/src/pages/index.tsx
new file mode 100644
index 00000000000..ebdd169f7de
--- /dev/null
+++ b/umijs-react-ts-demo/app1/src/pages/index.tsx
@@ -0,0 +1,9 @@
+import styles from './index.less';
+
+export default function IndexPage() {
+  return (
+    
+      
Page index
+    
+  );
+}
diff --git a/umijs-react-ts-demo/app1/tsconfig.json b/umijs-react-ts-demo/app1/tsconfig.json
new file mode 100644
index 00000000000..6d42f8cb4b2
--- /dev/null
+++ b/umijs-react-ts-demo/app1/tsconfig.json
@@ -0,0 +1,37 @@
+{
+  "compilerOptions": {
+    "target": "esnext",
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "importHelpers": true,
+    "jsx": "react-jsx",
+    "esModuleInterop": true,
+    "sourceMap": true,
+    "baseUrl": "./",
+    "strict": true,
+    "paths": {
+      "@/*": ["src/*"],
+      "@@/*": ["src/.umi/*"]
+    },
+    "allowSyntheticDefaultImports": true
+  },
+  "include": [
+    "mock/**/*",
+    "src/**/*",
+    "config/**/*",
+    ".umirc.ts",
+    "typings.d.ts"
+  ],
+  "exclude": [
+    "node_modules",
+    "lib",
+    "es",
+    "dist",
+    "typings",
+    "**/__test__",
+    "test",
+    "docs",
+    "tests"
+  ]
+}
diff --git a/umijs-react-ts-demo/app1/typings.d.ts b/umijs-react-ts-demo/app1/typings.d.ts
new file mode 100644
index 00000000000..06c8a5b8ca6
--- /dev/null
+++ b/umijs-react-ts-demo/app1/typings.d.ts
@@ -0,0 +1,10 @@
+declare module '*.css';
+declare module '*.less';
+declare module '*.png';
+declare module '*.svg' {
+  export function ReactComponent(
+    props: React.SVGProps,
+  ): React.ReactElement;
+  const url: string;
+  export default url;
+}
diff --git a/umijs-react-ts-demo/app2/.gitignore b/umijs-react-ts-demo/app2/.gitignore
new file mode 100644
index 00000000000..0dc2a3f9357
--- /dev/null
+++ b/umijs-react-ts-demo/app2/.gitignore
@@ -0,0 +1,9 @@
+/node_modules
+/.env.local
+/.umirc.local.ts
+/config/config.local.ts
+/src/.umi
+/src/.umi-production
+/src/.umi-test
+/dist
+.swc
diff --git a/umijs-react-ts-demo/app2/.umirc.ts b/umijs-react-ts-demo/app2/.umirc.ts
new file mode 100644
index 00000000000..a1a648af828
--- /dev/null
+++ b/umijs-react-ts-demo/app2/.umirc.ts
@@ -0,0 +1,64 @@
+import { defineConfig } from "umi";
+import { join } from 'path';
+
+const externals = {
+  react: "window.React",
+  "react-dom": "window.ReactDOM",
+}
+
+function webpackDeepPathImportWorkaround() {
+  const mod = require('module');
+  const resolveFilename = mod._resolveFilename;
+
+  mod._resolveFilename = function (request: string, parent: any, isMain: boolean, options: any) {
+    let newRequest = request;
+
+    if (/@umijs\/bundler-webpack\/compiled\/(lib|schemas)\//.test(request)) {
+      newRequest = request.replace(
+        /.*\/@umijs\/bundler-webpack\/compiled\/(lib|schemas)\//,
+        join(__dirname, './node_modules/webpack/$1', './'),
+      );
+    }
+
+    return resolveFilename.call(mod, newRequest, parent, isMain, options);
+  };
+}
+
+export default defineConfig({
+  routes: [
+    { path: "/", component: "index" },
+    { path: "/docs", component: "docs" },
+  ],
+  npmClient: 'pnpm',
+  chainWebpack: (config: any) => {
+    // reference https://github.com/umijs/umi/issues/10583
+    webpackDeepPathImportWorkaround();
+
+    const { ModuleFederationPlugin } = require('@module-federation/enhanced');
+
+    config.plugin('mf').use(ModuleFederationPlugin, [{
+      remotes: {
+        app1: 'app1@http://localhost:3001/remoteEntry.js'
+      },
+      shared: {
+        react: {
+          import: false,
+          singleton: true,
+          version: '18.2.0',
+        },
+        'react-dom': {
+          import: false,
+          singleton: true,
+          version: "16.14.0",
+        },
+      },
+      runtimePlugins: [require.resolve('./runtime.js')],
+    }])
+  },
+  headScripts: [
+    "https://cdn.bootcdn.net/ajax/libs/react/18.2.0/umd/react.production.min.js",
+    "https://cdn.bootcdn.net/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js",
+  ],
+  externals,
+  mfsu: false
+});
diff --git a/umijs-react-ts-demo/app2/package.json b/umijs-react-ts-demo/app2/package.json
new file mode 100644
index 00000000000..f520cadad50
--- /dev/null
+++ b/umijs-react-ts-demo/app2/package.json
@@ -0,0 +1,22 @@
+{
+  "private": true,
+  "author": "jie.q ",
+  "scripts": {
+    "dev": "umi dev",
+    "build": "umi build",
+    "postinstall": "umi setup",
+    "setup": "umi setup",
+    "start": "npm run dev"
+  },
+  "dependencies": {
+    "umi": "^4.1.1"
+  },
+  "devDependencies": {
+    "@module-federation/enhanced": "^0.0.10",
+    "@module-federation/runtime": "^0.0.10",
+    "@types/react": "18.2.48",
+    "@types/react-dom": "18.2.18",
+    "typescript": "^5.3.3",
+    "webpack": "5.89.0"
+  }
+}
diff --git a/umijs-react-ts-demo/app2/plugin.ts b/umijs-react-ts-demo/app2/plugin.ts
new file mode 100644
index 00000000000..f8a69ffa1cd
--- /dev/null
+++ b/umijs-react-ts-demo/app2/plugin.ts
@@ -0,0 +1,32 @@
+// See https://umijs.org/docs/guides/plugins
+import type { IApi } from 'umi';
+import { resolve } from 'path';
+import { readFileSync } from 'fs';
+// import { ModuleFederationPlugin } from '@module-federation/enhanced';
+
+export default (api: IApi) => {
+  // 实现 umi-plugin-mf-bootstrap, umi-plugin-mf-bootstrap-r 在 umi@4 下不兼容,会在 tmp 目录下生成 plugin-mfBootstrapR
+  api.onGenerateFiles(() => {
+    const path = api.env === 'production' ? './src/.umi-production/umi.ts' : './src/.umi/umi.ts';
+    const buffer = readFileSync(resolve(path));
+    const c = String(buffer);
+    // 防止热更新重复覆盖
+    if (c.includes('const { bootstrap, mount, unmount, update } = await import("./index")')) {
+      return;
+    }
+
+    api.writeTmpFile({
+      path: 'index.ts',
+      content: c,
+      noPluginDir: true
+    });
+    api.writeTmpFile({
+      path: 'umi.ts',
+      content: `
+const { bootstrap, mount, unmount, update } = await import("./index")
+export { bootstrap, mount, unmount, update }
+      `,
+      noPluginDir: true
+    });
+  });
+};
diff --git a/umijs-react-ts-demo/app2/runtime.js b/umijs-react-ts-demo/app2/runtime.js
new file mode 100644
index 00000000000..09c43820400
--- /dev/null
+++ b/umijs-react-ts-demo/app2/runtime.js
@@ -0,0 +1,21 @@
+// import { FederationRuntimePlugin } from '@module-federation/runtime/types';
+
+export default function () {
+  return {
+    name: 'umd-library-shared-plugin',
+    resolveShare(args) {
+      const { shareScopeMap, scope, pkgName, version } = args;
+
+      if (!['react', 'react-dom'].includes(pkgName)) {
+        return args;
+      }
+
+      args.resolver = function () {
+        shareScopeMap[scope][pkgName][version] = pkgName === 'react' ? window.React : window.ReactDOM; // replace local share scope manually with desired module
+        return shareScopeMap[scope][pkgName][version];
+      };
+
+      return args;
+    },
+  };
+}
diff --git a/umijs-react-ts-demo/app2/src/assets/yay.jpg b/umijs-react-ts-demo/app2/src/assets/yay.jpg
new file mode 100644
index 00000000000..e72bd8ffaec
Binary files /dev/null and b/umijs-react-ts-demo/app2/src/assets/yay.jpg differ
diff --git a/umijs-react-ts-demo/app2/src/layouts/index.less b/umijs-react-ts-demo/app2/src/layouts/index.less
new file mode 100644
index 00000000000..2e1d3f80e21
--- /dev/null
+++ b/umijs-react-ts-demo/app2/src/layouts/index.less
@@ -0,0 +1,10 @@
+.navs {
+  ul {
+    padding: 0;
+    list-style: none;
+    display: flex;
+  }
+  li {
+    margin-right: 1em;
+  }
+}
diff --git a/umijs-react-ts-demo/app2/src/layouts/index.tsx b/umijs-react-ts-demo/app2/src/layouts/index.tsx
new file mode 100644
index 00000000000..f4e26ef35fc
--- /dev/null
+++ b/umijs-react-ts-demo/app2/src/layouts/index.tsx
@@ -0,0 +1,21 @@
+import { Link, Outlet } from 'umi';
+import styles from './index.less';
+
+export default function Layout() {
+  return (
+    
+      
+        - 
+          Home
+        +
- 
+          Docs
+        +
- 
+          Github
+        +
+      
+    
+        
Yay! Welcome to umi!
+        
+           +
+        
+        
+          To get started, edit pages/index.tsx and save to reload.
+        
+