Skip to content

feat(nextjs-mf): App Router #3596

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 85 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
5b107fa
feat(enhanced): support layers
ScriptedAlchemy Nov 17, 2024
062706f
feat(enhanced): support layers
ScriptedAlchemy Nov 17, 2024
cfd9d01
feat(enhanced): layers for consume shared module
ScriptedAlchemy Nov 21, 2024
3e59c55
Merge branch 'main' into layers-support
ScriptedAlchemy Nov 21, 2024
536b110
Merge branch 'main' into layers-support
ScriptedAlchemy Nov 21, 2024
aed08e9
feat(enhanced): add issuerLayer support to consume shared
ScriptedAlchemy Nov 22, 2024
9fb164b
chore(enhanced): update test
ScriptedAlchemy Nov 25, 2024
a9d899c
chore(enhanced): update test
ScriptedAlchemy Nov 25, 2024
33a36d1
feat(enhanced): ConsumeSharedPlugin issuerLayer support
ScriptedAlchemy Nov 25, 2024
f0c5c50
chore: update tests for layer combos
ScriptedAlchemy Nov 25, 2024
578adbb
chore: update tests for layer combos
ScriptedAlchemy Nov 25, 2024
31f08d0
chore: update tests for layer combos
ScriptedAlchemy Nov 25, 2024
066ffa6
feat(enhanced): support direct layer
ScriptedAlchemy Nov 25, 2024
b70eb8d
Merge branch 'main' into layers-support
ScriptedAlchemy Nov 25, 2024
358ba00
fix(enhanced): update share options of share plugin
ScriptedAlchemy Nov 25, 2024
94d72ed
fix(enhanced): update share options of share plugin
ScriptedAlchemy Nov 25, 2024
91dbb12
chore(enhanced): refactor layers tests
ScriptedAlchemy Nov 25, 2024
514cf03
chore(enhanced): remove layer options from provider
ScriptedAlchemy Nov 25, 2024
359b0ca
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Nov 25, 2024
24ef6d0
Delete .cursorrules
ScriptedAlchemy Nov 25, 2024
9d9bff2
feat(enhanced): support layers in consume share
ScriptedAlchemy Nov 26, 2024
40ae817
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Nov 26, 2024
d1c68b3
fix(enhanced): rename requiredLayer to layer
ScriptedAlchemy Dec 2, 2024
22964f8
Merge remote-tracking branch 'origin/consume-share-layers' into consu…
ScriptedAlchemy Dec 2, 2024
9884030
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 2, 2024
3d8fa21
refactor(enhanced): pr review of consume share layering
ScriptedAlchemy Dec 3, 2024
69a2a52
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 3, 2024
04b8ffd
chore: locks
ScriptedAlchemy Dec 3, 2024
7852878
feat(enhanced): add request to consume share (#3307)
ScriptedAlchemy Dec 5, 2024
f35b1b1
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 5, 2024
b8df73e
chore: remove tt
ScriptedAlchemy Dec 9, 2024
b4b5a7b
chore: remove unused share
ScriptedAlchemy Dec 9, 2024
6f8f45e
refactor(enhanced): refactor type locations
ScriptedAlchemy Dec 10, 2024
875f516
feat(enhanced): ProvideSharedPlugin loader layer support (#3334)
ScriptedAlchemy Dec 12, 2024
673f6ca
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 12, 2024
20bae5b
chore: locks
ScriptedAlchemy Dec 12, 2024
a5774c8
chore(enhanced): add share plugin test
ScriptedAlchemy Dec 13, 2024
d44acbd
chore(enhanced): add share plugin test
ScriptedAlchemy Dec 13, 2024
1a33ac7
chore(enhanced): add share plugin test
ScriptedAlchemy Dec 13, 2024
1fc2b05
thing
ScriptedAlchemy Dec 13, 2024
29f6d73
thing
ScriptedAlchemy Dec 13, 2024
22127ee
chore(node): lint
ScriptedAlchemy Dec 13, 2024
8f9fb99
chore(node): lint
ScriptedAlchemy Dec 13, 2024
243f1bc
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 13, 2024
0c665be
feat(enhanced): layers support in module code generation (#3371)
ScriptedAlchemy Dec 29, 2024
ffdaf0b
chore: changeset
ScriptedAlchemy Dec 31, 2024
687365f
feat(enhanced): Layer via composite shareKey (#3415)
ScriptedAlchemy Dec 31, 2024
4ef6efb
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Dec 31, 2024
81d2365
chore: locks
ScriptedAlchemy Dec 31, 2024
6f952fd
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Jan 1, 2025
5fce760
chore: locks
ScriptedAlchemy Jan 1, 2025
1fba24f
fix(enhanced): cache consume module layer
ScriptedAlchemy Jan 2, 2025
7af571f
fix(nextjs-mf): enable app router shares and disable hard fail
ScriptedAlchemy Jan 2, 2025
7a178c0
chore: add host remote app router
ScriptedAlchemy Jan 2, 2025
10f2b73
feat(nextjs-mf): update module share for rsc
ScriptedAlchemy Jan 3, 2025
e122bf4
feat(nextjs-mf): update module share for rsc
ScriptedAlchemy Jan 21, 2025
c3729a7
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Feb 18, 2025
e6a109d
chore: fix schema validation eror
ScriptedAlchemy Feb 18, 2025
ee0726d
chore: fix schema validation errors
ScriptedAlchemy Feb 18, 2025
2fc6497
fix(enhanced): schema validation
ScriptedAlchemy Feb 18, 2025
baaeb27
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Feb 19, 2025
55abb84
chore: locks
ScriptedAlchemy Feb 19, 2025
cfca731
chore: update schema
ScriptedAlchemy Feb 19, 2025
6e6ef06
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Feb 25, 2025
41e1a84
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Mar 12, 2025
aef1bb2
chore: locks
ScriptedAlchemy Mar 12, 2025
fb936d3
chore: fix json schema
ScriptedAlchemy Mar 12, 2025
0ff2e2c
chore: fix json schema
ScriptedAlchemy Mar 12, 2025
42bf94c
chore: fix json schema
ScriptedAlchemy Mar 12, 2025
2c52030
feat(enhanced): implement multiple share scope support (#3524)
ScriptedAlchemy Mar 14, 2025
83261cc
chore: add next with app router
ScriptedAlchemy Mar 14, 2025
fc201b9
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Mar 14, 2025
a3899fc
chore: add next with app router
ScriptedAlchemy Mar 14, 2025
25277fc
chore: update deps
ScriptedAlchemy Mar 14, 2025
b23bb46
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Mar 14, 2025
f0b2404
chore: update deps
ScriptedAlchemy Mar 14, 2025
01b6767
chore: update deps
ScriptedAlchemy Mar 14, 2025
cc658b9
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Mar 14, 2025
6835348
chore: update deps
ScriptedAlchemy Mar 14, 2025
a8b5055
fix: add next apps to workspace
ScriptedAlchemy Mar 14, 2025
4431551
feat(nextjs-mf): app router support
ScriptedAlchemy Mar 15, 2025
dc6d0c0
Merge branch 'main' into consume-share-layers
ScriptedAlchemy Mar 15, 2025
3fe3803
feat(nextjs-mf): app router support
ScriptedAlchemy Mar 16, 2025
d25ff57
Merge branch 'consume-share-layers' into app-router-support
ScriptedAlchemy Mar 18, 2025
df4a103
Merge branch 'main' into app-router-support
ScriptedAlchemy Apr 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .changeset/ai-hungry-bear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"@module-federation/enhanced": minor
---

Enhancements to layer handling in module federation tests and configuration.

- Improved handling of `shareKey` for layers within `ConsumeSharedPlugin` and `ProvideSharedPlugin`.
- Conditionally prepend the `shareKey` with the `layer` if applicable.
- Introduced new layer configurations to support more nuanced federation scenarios that consider multiple layers of dependency.
```
9 changes: 9 additions & 0 deletions .changeset/ai-sleepy-fox.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@module-federation/enhanced": patch
---

Refactored module sharing configuration handling.

- Simplified plugin schema for better maintainability
- Improved layer-based module sharing test coverage
- Removed redundant plugin exports
6 changes: 6 additions & 0 deletions .changeset/ai-sleepy-tiger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@module-federation/runtime": minor
---

- Added a new property 'layer' of type string or null to SharedConfig.
```
5 changes: 5 additions & 0 deletions .changeset/brown-badgers-fetch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/enhanced': minor
---

support request option on ConsumeSharePlugin. Allows matching requests like the object key of shared does
5 changes: 5 additions & 0 deletions .changeset/shy-snails-battle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@module-federation/enhanced': minor
---

Layer support for Provide Share Plugin
12 changes: 5 additions & 7 deletions apps/next-app-router/next-app-router-4001/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import '#/styles/globals.css';
import { AddressBar } from '#/ui/address-bar';
import Byline from '#/ui/byline';
// import { AddressBar } from '#/ui/address-bar';
// import Byline from '#/ui/byline';
import { GlobalNav } from '#/ui/global-nav';
import { Metadata } from 'next';
// import { Metadata } from 'next';

export const metadata: Metadata = {
title: {
Expand Down Expand Up @@ -36,15 +36,13 @@ export default function RootLayout({
<div className="lg:pl-72">
<div className="mx-auto max-w-4xl space-y-8 px-2 pt-20 lg:px-8 lg:py-8">
<div className="rounded-lg bg-vc-border-gradient p-px shadow-lg shadow-black/20">
<div className="rounded-lg bg-black">
<AddressBar />
</div>
<div className="rounded-lg bg-black">{/*<AddressBar />*/}</div>
</div>

<div className="rounded-lg bg-vc-border-gradient p-px shadow-lg shadow-black/20">
<div className="rounded-lg bg-black p-3.5 lg:p-6">{children}</div>
</div>
<Byline />
{/*<Byline />*/}
</div>
</div>
</body>
Expand Down
4 changes: 2 additions & 2 deletions apps/next-app-router/next-app-router-4001/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ const nextConfig = {
// Core UI Components
'./Button': './ui/button',
// './Header': isServer ? './ui/header?rsc' : './ui/header?shared',
'./Footer': './ui/footer',
// './Footer': './ui/footer',
// './GlobalNav(rsc)': isServer ? './ui/global-nav?rsc' : './ui/global-nav',
// './GlobalNav(ssr)': isServer ? './ui/global-nav?ssr' : './ui/global-nav',
'./GlobalNav': './ui/global-nav',
// './GlobalNav': './ui/global-nav',
//
// // Product Related Components
// './ProductCard': './ui/product-card',
Expand Down
6 changes: 3 additions & 3 deletions apps/next-app-router/next-app-router-4001/project.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "next-app-router-4001",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "apps/next-app-router-4001",
"sourceRoot": "apps/next-app-router/next-app-router-4001",
"projectType": "application",
"tags": [],
"targets": {
Expand All @@ -27,8 +27,8 @@
"serve": {
"executor": "nx:run-commands",
"options": {
"command": "pnpm dev",
"cwd": "apps/next-app-router-4001"
"command": "npm run dev",
"cwd": "apps/next-app-router/next-app-router-4001"
},
"dependsOn": [
{
Expand Down
159 changes: 121 additions & 38 deletions packages/nextjs-mf/src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ type ExtendedSharedConfig = sharePlugin.SharedConfig & {
shareKey?: string;
};

const WEBPACK_LAYERS_NAMES = {
export const WEBPACK_LAYERS_NAMES = {
/**
* The layer for the shared code between the client and server bundles.
*/
Expand Down Expand Up @@ -58,7 +58,7 @@ const createSharedConfig = (
) => {
return layers.reduce(
(acc, layer) => {
const key = layer ? `${name}-${layer}` : name;
const key = layer ? `${layer}-${name}` : name;
acc[key] = {
singleton: true,
requiredVersion: false,
Expand All @@ -67,6 +67,7 @@ const createSharedConfig = (
request: options.request ?? name,
layer,
issuerLayer: layer,
shareScope: layer ? [layer] : undefined,
};
return acc;
},
Expand All @@ -85,11 +86,30 @@ const navigationLayers = [
WEBPACK_LAYERS_NAMES.serverSideRendering,
];

const reactShares = createSharedConfig('react', defaultLayers);
const reactShares = createSharedConfig('react', defaultLayers, {
request: 'react',
import: undefined,
});
const reactDomShares = createSharedConfig('react', defaultLayers, {
request: 'react-dom',
});
const jsxRuntimeShares = createSharedConfig('react/', navigationLayers, {
const jsxRuntimeShares = createSharedConfig(
'react/jsx-runtime',
navigationLayers,
{
request: 'react/jsx-runtime',
import: undefined,
},
);
const jsxDevRuntimeShares = createSharedConfig(
'react/jsx-dev-runtime',
navigationLayers,
{
request: 'react/jsx-dev-runtime',
import: undefined,
},
);
const prefixReact = createSharedConfig('react/', defaultLayers, {
request: 'react/',
import: undefined,
});
Expand All @@ -110,11 +130,83 @@ const nextNavigationShares = createSharedConfig(
* @property {string} key.layer - The webpack layer this shared module belongs to.
* @property {string|string[]} key.issuerLayer - The webpack layer that can import this shared module.
*/
export const DEFAULT_SHARE_SCOPE: moduleFederationPlugin.SharedObject = {
// ...reactShares,
// ...reactDomShares,
// ...nextNavigationShares,
// ...jsxRuntimeShares,
// Group React related packages
const reactGroup = {
react: {
singleton: true,
import: false,
},
'ssr-react': {
requiredVersion: false,
request: 'react',
import: 'next/dist/server/route-modules/app-page/vendored/ssr/react.js',
singleton: true,
shareKey: 'react',
layer: WEBPACK_LAYERS_NAMES.serverSideRendering,
issuerLayer: WEBPACK_LAYERS_NAMES.serverSideRendering,
shareScope: [WEBPACK_LAYERS_NAMES.serverSideRendering],
},
'rsc-react': {
requiredVersion: false,
singleton: true,
shareKey: 'react',
request: 'react',
import: 'next/dist/server/route-modules/app-page/vendored/rsc/react.js',
layer: WEBPACK_LAYERS_NAMES.reactServerComponents,
issuerLayer: WEBPACK_LAYERS_NAMES.reactServerComponents,
shareScope: [WEBPACK_LAYERS_NAMES.reactServerComponents],
},
};

const reactJsxRuntimeGroup = {
'react/jsx-dev-runtime': {
singleton: true,
import: false,
},
// "react/jsx-dev-runtime-ssr": {
// singleton: true,
// shareKey: 'react/jsx-dev-runtime',
// request: 'react/jsx-dev-runtime',
// layer: WEBPACK_LAYERS_NAMES.serverSideRendering,
// issuerLayer: WEBPACK_LAYERS_NAMES.serverSideRendering,
// shareScope: WEBPACK_LAYERS_NAMES.serverSideRendering,
// },
// "react/jsx-dev-runtime-rsc": {
// request: 'react/jsx-dev-runtime',
// singleton: true,
// shareKey: 'react/jsx-dev-runtime',
// layer: WEBPACK_LAYERS_NAMES.reactServerComponents,
// issuerLayer: WEBPACK_LAYERS_NAMES.reactServerComponents,
// shareScope: WEBPACK_LAYERS_NAMES.reactServerComponents,
// }
};

// Group React-DOM related packages
const reactDomGroup = {
// "react-dom": {
// singleton: true,
// import: false,
// },
// "rsc-react-dom": {
// singleton: true,
// shareKey: 'react-dom',
// request: 'react-dom',
// layer: WEBPACK_LAYERS_NAMES.reactServerComponents,
// issuerLayer: WEBPACK_LAYERS_NAMES.reactServerComponents,
// shareScope: WEBPACK_LAYERS_NAMES.reactServerComponents,
// },
// "react-dom-ssr": {
// request: 'react-dom',
// singleton: true,
// shareKey: 'react-dom',
// layer: WEBPACK_LAYERS_NAMES.serverSideRendering,
// issuerLayer: WEBPACK_LAYERS_NAMES.serverSideRendering,
// shareScope: WEBPACK_LAYERS_NAMES.serverSideRendering,
// }
};

// Group Next.js related packages
const nextGroup = {
'next/dynamic': {
requiredVersion: undefined,
singleton: true,
Expand Down Expand Up @@ -145,34 +237,10 @@ export const DEFAULT_SHARE_SCOPE: moduleFederationPlugin.SharedObject = {
singleton: true,
import: undefined,
},
react: {
singleton: true,
requiredVersion: false,
import: false,
},
'react/': {
singleton: true,
requiredVersion: false,
import: false,
},
'react-dom/': {
singleton: true,
requiredVersion: false,
import: false,
},
'react-dom': {
singleton: true,
requiredVersion: false,
import: false,
},
'react/jsx-dev-runtime': {
singleton: true,
requiredVersion: false,
},
'react/jsx-runtime': {
singleton: true,
requiredVersion: false,
},
};

// Group styled-jsx related packages
const styledJsxGroup = {
'styled-jsx': {
singleton: true,
import: undefined,
Expand All @@ -193,6 +261,15 @@ export const DEFAULT_SHARE_SCOPE: moduleFederationPlugin.SharedObject = {
},
};

//@ts-ignore
export const DEFAULT_SHARE_SCOPE: moduleFederationPlugin.SharedObject = {
...reactGroup,
...reactDomGroup,
// ...nextGroup,
// ...styledJsxGroup,
// ...reactJsxRuntimeGroup,
};

/**
* Defines a default share scope for the browser environment.
* This function takes the DEFAULT_SHARE_SCOPE and sets eager to undefined and import to undefined for all entries.
Expand All @@ -206,7 +283,13 @@ export const DEFAULT_SHARE_SCOPE: moduleFederationPlugin.SharedObject = {
export const DEFAULT_SHARE_SCOPE_BROWSER: moduleFederationPlugin.SharedObject =
Object.entries(DEFAULT_SHARE_SCOPE).reduce((acc, item) => {
const [key, value] = item as [string, moduleFederationPlugin.SharedConfig];

// if(key.startsWith(WEBPACK_LAYERS_NAMES.reactServerComponents) || key.startsWith(WEBPACK_LAYERS_NAMES.serverSideRendering)) {
// return acc
// }
//
// if(key === 'next-navigation') {
// return acc;
// }
// Set eager and import to undefined for all entries, except for the ones specified above
acc[key] = { ...value, import: undefined };

Expand Down
21 changes: 13 additions & 8 deletions packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { ModuleFederationPlugin } from '@module-federation/enhanced/webpack';
import type { moduleFederationPlugin } from '@module-federation/sdk';

import path from 'path';
import { WEBPACK_LAYERS_NAMES } from '../../internal';
/**
* NextFederationPlugin is a webpack plugin that handles Next.js application federation using Module Federation.
*/
Expand Down Expand Up @@ -108,14 +109,14 @@ export class NextFederationPlugin {
p?.constructor?.name === 'BuildManifestPlugin',
);

if (manifestPlugin) {
//@ts-ignore
if (manifestPlugin?.appDirEnabled) {
throw new Error(
'App Directory is not supported by nextjs-mf. Use only pages directory, do not open git issues about this',
);
}
}
// if (manifestPlugin) {
// //@ts-ignore
// if (manifestPlugin?.appDirEnabled) {
// throw new Error(
// 'App Directory is not supported by nextjs-mf. Use only pages directory, do not open git issues about this',
// );
// }
// }

const compilerValid = validateCompilerOptions(compiler);
const pluginValid = validatePluginOptions(this._options);
Expand Down Expand Up @@ -215,6 +216,10 @@ export class NextFederationPlugin {
remotes: {
...this._options.remotes,
},
shareScope: Object.values({
...WEBPACK_LAYERS_NAMES,
default: 'default',
}),
shared: {
...defaultShared,
...this._options.shared,
Expand Down
11 changes: 6 additions & 5 deletions packages/nextjs-mf/src/plugins/container/runtimePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ export default function (): FederationRuntimePlugin {
) {
return args;
}
console.log(args);
const shareScopeMap = args.shareScopeMap;
const scope = args.scope;
const pkgName = args.pkgName;
Expand All @@ -237,11 +238,11 @@ export default function (): FederationRuntimePlugin {
if (!host.options.shared[pkgName]) {
return args;
}
args.resolver = function () {
shareScopeMap[scope][pkgName][version] =
host.options.shared[pkgName][0];
return shareScopeMap[scope][pkgName][version];
};
// args.resolver = function () {
// shareScopeMap[scope][pkgName][version] =
// host.options.shared[pkgName][0];
// return shareScopeMap[scope][pkgName][version];
// };
return args;
},
beforeLoadShare: async function (args: any) {
Expand Down
Loading