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"