diff --git a/e2e/fixtures/module-federation.consumer/.gitignore b/e2e/fixtures/module-federation.consumer/.gitignore
new file mode 100644
index 000000000..de4d1f007
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/.gitignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/e2e/fixtures/module-federation.consumer/expect.js b/e2e/fixtures/module-federation.consumer/expect.js
new file mode 100644
index 000000000..3cf2fe3b1
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/expect.js
@@ -0,0 +1,22 @@
+const assert = require("assert");
+const { parseBuildResult } = require("../../../scripts/test-utils");
+const { files } = parseBuildResult(__dirname);
+
+const manifest = JSON.parse(files["mf-manifest.json"]);
+
+assert(
+ manifest.remotes[0].alias === 'producer'
+ && manifest.remotes[0].federationContainerName === 'producer'
+ && manifest.remotes[0].moduleName === 'App',
+ "should include mf remotes info"
+)
+
+assert(
+ manifest.shared.map(s => s.name).sort().join(",") === "react,react-dom",
+ "should include mf shared dependencies"
+)
+
+assert(
+ manifest.shared.every(s => s.assets.js.sync.length !== 0),
+ "should include mf shared assets"
+)
diff --git a/e2e/fixtures/module-federation.consumer/mako.config.json b/e2e/fixtures/module-federation.consumer/mako.config.json
new file mode 100644
index 000000000..dcfe4ae67
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/mako.config.json
@@ -0,0 +1,15 @@
+{
+ "entry": {
+ "app1": "./src/index.ts"
+ },
+ "minify": false,
+ "moduleFederation": {
+ "name": "consumer",
+ "remotes": {
+ "producer": "producer@http://localhost:3000/remoteEntry.js"
+ },
+ "shared": { "react": { "eager": true }, "react-dom": { "eager": true } },
+ "manifest": true,
+ "implementation": "../../../../../packages/mako/node_modules/@module-federation/webpack-bundler-runtime"
+ }
+}
diff --git a/e2e/fixtures/module-federation.consumer/package.json b/e2e/fixtures/module-federation.consumer/package.json
new file mode 100644
index 000000000..723a9fb2d
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "mf-consumer",
+ "version": "0.0.1",
+ "dependencies": {
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "@types/react": "18.2.0",
+ "@types/react-dom": "18.2.0"
+ }
+}
diff --git a/e2e/fixtures/module-federation.consumer/public/index.html b/e2e/fixtures/module-federation.consumer/public/index.html
new file mode 100644
index 000000000..7e0bd8d29
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/public/index.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/e2e/fixtures/module-federation.consumer/src/App.tsx b/e2e/fixtures/module-federation.consumer/src/App.tsx
new file mode 100644
index 000000000..0d9833d2e
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/src/App.tsx
@@ -0,0 +1,26 @@
+import React from 'react';
+
+// @ts-ignore
+const RemoteComp = React.lazy(() => import('producer/App'));
+
+const App = () => {
+ return (
+
+
+
Consumer App
+
+
+
+
+
+ );
+};
+
+export default App;
diff --git a/e2e/fixtures/module-federation.consumer/src/bootstrap.tsx b/e2e/fixtures/module-federation.consumer/src/bootstrap.tsx
new file mode 100644
index 000000000..b597a4423
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/src/bootstrap.tsx
@@ -0,0 +1,5 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './App';
+
+ReactDOM.render(, document.getElementById('root'));
diff --git a/e2e/fixtures/module-federation.consumer/src/index.ts b/e2e/fixtures/module-federation.consumer/src/index.ts
new file mode 100644
index 000000000..e59d6a0ad
--- /dev/null
+++ b/e2e/fixtures/module-federation.consumer/src/index.ts
@@ -0,0 +1 @@
+import './bootstrap';
diff --git a/e2e/fixtures/module-federation.producer/.gitignore b/e2e/fixtures/module-federation.producer/.gitignore
new file mode 100644
index 000000000..de4d1f007
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/.gitignore
@@ -0,0 +1,2 @@
+dist
+node_modules
diff --git a/e2e/fixtures/module-federation.producer/expect.js b/e2e/fixtures/module-federation.producer/expect.js
new file mode 100644
index 000000000..ab5ff0183
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/expect.js
@@ -0,0 +1,30 @@
+const assert = require("assert");
+const { parseBuildResult } = require("../../../scripts/test-utils");
+const { files } = parseBuildResult(__dirname);
+
+const manifest = JSON.parse(files["mf-manifest.json"]);
+
+assert(
+ manifest.metaData.remoteEntry.name === 'remoteEntry.js',
+ "should generate mf contanier entry"
+)
+
+assert(
+ manifest.exposes[0].name === 'App',
+ "should include mf exposes"
+)
+
+assert(
+ manifest.exposes[0].assets.js.sync.length !== 0,
+ "should include mf exposes assets"
+)
+
+assert(
+ manifest.shared.map(s => s.name).sort().join(",") === "react,react-dom",
+ "should include mf shared dependencies"
+)
+
+assert(
+ manifest.shared.every(s => s.assets.js.sync.length !== 0),
+ "should include mf shared assets"
+)
diff --git a/e2e/fixtures/module-federation.producer/mako.config.json b/e2e/fixtures/module-federation.producer/mako.config.json
new file mode 100644
index 000000000..e966ee81d
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/mako.config.json
@@ -0,0 +1,16 @@
+{
+ "entry": {
+ "app2": "./src/index.ts"
+ },
+ "publicPath": "auto",
+ "moduleFederation": {
+ "name": "producer",
+ "filename": "remoteEntry.js",
+ "exposes": {
+ "./App": "./src/App.tsx"
+ },
+ "shared": { "react": {}, "react-dom": {} },
+ "manifest": true,
+ "implementation": "../../../../../packages/mako/node_modules/@module-federation/webpack-bundler-runtime"
+ }
+}
diff --git a/e2e/fixtures/module-federation.producer/package.json b/e2e/fixtures/module-federation.producer/package.json
new file mode 100644
index 000000000..c803f552e
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "mf-producer",
+ "version": "0.0.1",
+ "dependencies": {
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "@types/react": "18.2.0",
+ "@types/react-dom": "18.2.0"
+ }
+}
diff --git a/e2e/fixtures/module-federation.producer/public/index.html b/e2e/fixtures/module-federation.producer/public/index.html
new file mode 100644
index 000000000..5de48ef2f
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/public/index.html
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/e2e/fixtures/module-federation.producer/src/App.tsx b/e2e/fixtures/module-federation.producer/src/App.tsx
new file mode 100644
index 000000000..2a1875c7f
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/src/App.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+
+const App = () => {
+ return (
+
+
Widget App2
+
+ );
+};
+
+export default App;
diff --git a/e2e/fixtures/module-federation.producer/src/bootstrap.tsx b/e2e/fixtures/module-federation.producer/src/bootstrap.tsx
new file mode 100644
index 000000000..ae31e4134
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/src/bootstrap.tsx
@@ -0,0 +1,6 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+
+import App from './App';
+
+ReactDOM.render(, document.getElementById('root'));
diff --git a/e2e/fixtures/module-federation.producer/src/index.ts b/e2e/fixtures/module-federation.producer/src/index.ts
new file mode 100644
index 000000000..b93c7a026
--- /dev/null
+++ b/e2e/fixtures/module-federation.producer/src/index.ts
@@ -0,0 +1 @@
+import('./bootstrap');
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 073c28112..503c5d6c9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -191,6 +191,36 @@ importers:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
+ e2e/fixtures/module-federation.consumer:
+ dependencies:
+ '@types/react':
+ specifier: 18.2.0
+ version: 18.2.0
+ '@types/react-dom':
+ specifier: 18.2.0
+ version: 18.2.0
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+
+ e2e/fixtures/module-federation.producer:
+ dependencies:
+ '@types/react':
+ specifier: 18.2.0
+ version: 18.2.0
+ '@types/react-dom':
+ specifier: 18.2.0
+ version: 18.2.0
+ react:
+ specifier: 18.2.0
+ version: 18.2.0
+ react-dom:
+ specifier: 18.2.0
+ version: 18.2.0(react@18.2.0)
+
examples/config-externals: {}
examples/dead-simple: {}
@@ -655,7 +685,7 @@ packages:
'@emotion/hash': 0.8.0
'@emotion/unitless': 0.7.5
classnames: 2.3.2
- csstype: 3.1.2
+ csstype: 3.1.3
rc-util: 5.37.0(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
@@ -5889,7 +5919,6 @@ packages:
/@types/prop-types@15.7.5:
resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==}
- dev: true
/@types/ps-tree@1.1.2:
resolution: {integrity: sha512-ZREFYlpUmPQJ0esjxoG1fMvB2HNaD3z+mjqdSosZvd3RalncI9NEur73P8ZJz4YQdL64CmV1w0RuqoRUlhQRBw==}
@@ -5903,6 +5932,12 @@ packages:
resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==}
dev: true
+ /@types/react-dom@18.2.0:
+ resolution: {integrity: sha512-8yQrvS6sMpSwIovhPOwfyNf2Wz6v/B62LFSVYQ85+Rq3tLsBIG7rP5geMxaijTUxSkrO6RzN/IRuIAADYQsleA==}
+ dependencies:
+ '@types/react': 18.2.7
+ dev: false
+
/@types/react-dom@18.2.4:
resolution: {integrity: sha512-G2mHoTMTL4yoydITgOGwWdWMVd8sNgyEP85xVmMKAPUBwQWm9wBPQUmvbeF4V3WBY1P7mmL4BkjQ0SqUpf1snw==}
dependencies:
@@ -5933,20 +5968,26 @@ packages:
'@types/react': 18.2.7
dev: true
+ /@types/react@18.2.0:
+ resolution: {integrity: sha512-0FLj93y5USLHdnhIhABk83rm8XEGA7kH3cr+YUlvxoUGp1xNt/DINUMvqPxLyOQMzLmZe8i4RTHbvb8MC7NmrA==}
+ dependencies:
+ '@types/prop-types': 15.7.5
+ '@types/scheduler': 0.16.3
+ csstype: 3.1.3
+ dev: false
+
/@types/react@18.2.7:
resolution: {integrity: sha512-ojrXpSH2XFCmHm7Jy3q44nXDyN54+EYKP2lBhJ2bqfyPj6cIUW/FZW/Csdia34NQgq7KYcAlHi5184m4X88+yw==}
dependencies:
'@types/prop-types': 15.7.5
'@types/scheduler': 0.16.3
csstype: 3.1.3
- dev: true
/@types/resolve@1.20.6:
resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==}
/@types/scheduler@0.16.3:
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
- dev: true
/@types/semver@7.5.8:
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
@@ -8999,7 +9040,6 @@ packages:
/csstype@3.1.3:
resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
- dev: true
/current-script-polyfill@1.0.0:
resolution: {integrity: sha512-qv8s+G47V6Hq+g2kRE5th+ASzzrL7b6l+tap1DHKK25ZQJv3yIFhH96XaQ7NGL+zRW3t/RDbweJf/dJDe5Z5KA==}
diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml
index 58b2f7b75..b5d16bf03 100644
--- a/pnpm-workspace.yaml
+++ b/pnpm-workspace.yaml
@@ -3,7 +3,7 @@ packages:
- "client"
- "crates/binding"
- "packages/*"
- - "crates/mako/test/compile/auto-code-splitting"
+ - "e2e/fixtures/module-federation.*"
- "e2e/fixtures.umi/react-16"
- "e2e/fixtures.umi/config.less.plugins"
- "e2e/fixtures.umi/stable-hash"