diff --git a/.changeset/ai-eager-wolf.md b/.changeset/ai-eager-wolf.md new file mode 100644 index 00000000000..ab5fe276767 --- /dev/null +++ b/.changeset/ai-eager-wolf.md @@ -0,0 +1,12 @@ +--- +"@module-federation/runtime-core": minor +--- + +Added support for OR ranges in semantic version satisfaction logic with comprehensive unit tests. + +- Implemented parsing for OR (||) conditions in version ranges. + - Split input ranges by || to evaluate alternatives individually. + - Ensured logical handling of wildcards '*' and 'x' within ranges. +- Refactored internal parsing to support more complex range constructs. +- Added comprehensive test cases to cover diverse scenarios for OR range support. +- Introduced error handling during range processing, with console logging for tracking issues. diff --git a/.changeset/ai-happy-fox.md b/.changeset/ai-happy-fox.md new file mode 100644 index 00000000000..51821121aff --- /dev/null +++ b/.changeset/ai-happy-fox.md @@ -0,0 +1,12 @@ +--- +"@module-federation/nextjs-mf": minor +--- + +Refactor and enhance module federation support for Next.js. + +- Introduced `getShareScope` function to dynamically generate the default share scope based on the client or server environment, replacing static DEFAULT_SHARE_SCOPE declarations. +- Implemented `RscManifestInterceptPlugin` to intercept and modify client reference manifests, ensuring proper prefix handling. +- Refined server-side externals handling to ensure shared federation modules are bundled. +- Simplified and modularized sharing logic by creating distinct functions for React, React DOM, React JSX Runtime, and React JSX Dev Runtime package configurations. +- Captured the original webpack public path for potential use in plugins and adjustments. +- Enhanced logging for debug tracing of shared module resolution processes in runtimePlugin. diff --git a/.changeset/ai-happy-mouse.md b/.changeset/ai-happy-mouse.md new file mode 100644 index 00000000000..82ec31613a9 --- /dev/null +++ b/.changeset/ai-happy-mouse.md @@ -0,0 +1,9 @@ +--- +"@module-federation/sdk": minor +--- + +Added a new option to improve path resolution in ModuleFederationPlugin options. + +- Introduced `nodeModulesReconstructedLookup` option in `ModuleFederationPluginOptions` + - Enhances support for reconstructed lookup of node_modules paths +- The new option is a boolean and is optional. \ No newline at end of file diff --git a/.changeset/ai-hungry-bear.md b/.changeset/ai-hungry-bear.md new file mode 100644 index 00000000000..444a92082bf --- /dev/null +++ b/.changeset/ai-hungry-bear.md @@ -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. +``` diff --git a/.changeset/ai-noisy-wolf.md b/.changeset/ai-noisy-wolf.md new file mode 100644 index 00000000000..7a03cd46821 --- /dev/null +++ b/.changeset/ai-noisy-wolf.md @@ -0,0 +1,11 @@ +--- +"@module-federation/enhanced": minor +--- + +Add advanced sharing capabilities in Module Federation + +- Expanded `IncludeExcludeOptions` to support `request`, `version`, and `fallbackVersion` filters for finer control of module sharing inclusion and exclusion, allowing developers to target specific module versions or paths when sharing. + - Enhanced the configuration of `ConsumeSharedModule`, `ConsumeSharedPlugin`, `ProvideSharedPlugin`, and `SharePlugin` to leverage these filtering options. +- Implemented new experimental features under `experiments`: `nodeModulesReconstructedLookup`, enabling more robust and flexible path reconstructions when consuming or providing shared modules, thus improving compatibility with monorepos and complex project structures. +- Updated internal schema validation and error handling to provide more informative feedback and operational resilience against misconfigurations or missing information. +- Introduced comprehensive test coverage for new features and plugin behaviors, ensuring robust validation against various edge cases and scenarios within module sharing operations. \ No newline at end of file diff --git a/.changeset/ai-sleepy-fox.md b/.changeset/ai-sleepy-fox.md new file mode 100644 index 00000000000..36d84f71503 --- /dev/null +++ b/.changeset/ai-sleepy-fox.md @@ -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 diff --git a/.changeset/ai-sleepy-tiger.md b/.changeset/ai-sleepy-tiger.md new file mode 100644 index 00000000000..6c11ece998e --- /dev/null +++ b/.changeset/ai-sleepy-tiger.md @@ -0,0 +1,6 @@ +--- +"@module-federation/runtime": minor +--- + +- Added a new property 'layer' of type string or null to SharedConfig. +``` diff --git a/.changeset/brown-badgers-fetch.md b/.changeset/brown-badgers-fetch.md new file mode 100644 index 00000000000..00d28f1f096 --- /dev/null +++ b/.changeset/brown-badgers-fetch.md @@ -0,0 +1,5 @@ +--- +'@module-federation/enhanced': minor +--- + +support request option on ConsumeSharePlugin. Allows matching requests like the object key of shared does diff --git a/.changeset/shy-snails-battle.md b/.changeset/shy-snails-battle.md new file mode 100644 index 00000000000..8d4fb5ec2f1 --- /dev/null +++ b/.changeset/shy-snails-battle.md @@ -0,0 +1,5 @@ +--- +'@module-federation/enhanced': minor +--- + +Layer support for Provide Share Plugin diff --git a/.cursor/rules/nx-rules.mdc b/.cursor/rules/nx-rules.mdc new file mode 100644 index 00000000000..ed6c085a49b --- /dev/null +++ b/.cursor/rules/nx-rules.mdc @@ -0,0 +1,41 @@ +--- +description: +globs: +alwaysApply: true +--- + +// This file is automatically generated by Nx Console + +You are in an nx workspace using Nx 0.0.0 and npm as the package manager. + +You have access to the Nx MCP server and the tools it provides. Use them. Follow these guidelines in order to best help the user: + +# General Guidelines +- When answering questions, use the nx_workspace tool first to gain an understanding of the workspace architecture +- For questions around nx configuration, best practices or if you're unsure, use the nx_docs tool to get relevant, up-to-date docs!! Always use this instead of assuming things about nx configuration +- If the user needs help with an Nx configuration or project graph error, use the 'nx_workspace' tool to get any errors +- To help answer questions about the workspace structure or simply help with demonstrating how tasks depend on each other, use the 'nx_visualize_graph' tool + +# Generation Guidelines +If the user wants to generate something, use the following flow: + +- learn about the nx workspace and any specifics the user needs by using the 'nx_workspace' tool and the 'nx_project_details' tool if applicable +- get the available generators using the 'nx_generators' tool +- decide which generator to use. If no generators seem relevant, check the 'nx_available_plugins' tool to see if the user could install a plugin to help them +- get generator details using the 'nx_generator_schema' tool +- you may use the 'nx_docs' tool to learn more about a specific generator or technology if you're unsure +- decide which options to provide in order to best complete the user's request. Don't make any assumptions and keep the options minimalistic +- open the generator UI using the 'nx_open_generate_ui' tool +- wait for the user to finish the generator +- read the generator log file using the 'nx_read_generator_log' tool +- use the information provided in the log file to answer the user's question or continue with what they were doing + + +# CI Error Guidelines +If the user wants help with fixing an error in their CI pipeline, use the following flow: +- Retrieve the list of current CI Pipeline Executions (CIPEs) using the 'nx_cloud_cipe_details' tool +- If there are any errors, use the 'nx_cloud_fix_cipe_failure' tool to retrieve the logs for a specific task +- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary +- Make sure that the problem is fixed by running the task that you passed into the 'nx_cloud_fix_cipe_failure' tool + + diff --git a/.cursor/rules/running-tests.mdc b/.cursor/rules/running-tests.mdc new file mode 100644 index 00000000000..dfc8df4c75f --- /dev/null +++ b/.cursor/rules/running-tests.mdc @@ -0,0 +1,6 @@ +--- +description: +globs: packages/enhanced/* +alwaysApply: false +--- +use pnpm enhanced:jest to test this diff --git a/.cursorignore b/.cursorignore index 9ff4e05b449..5b264c56cf9 100644 --- a/.cursorignore +++ b/.cursorignore @@ -2,7 +2,7 @@ **/.cache/ **/.temp/ **/coverage/ -**/dist/ +!**/dist/ # Explicitly ignore specific packages packages/typescript/ diff --git a/.cursorrules b/.cursorrules index a8aee8134d2..e69de29bb2d 100644 --- a/.cursorrules +++ b/.cursorrules @@ -1,40 +0,0 @@ -an assistant that engages in extremely thorough, self-questioning reasoning. Your approach mirrors human stream-of- -consciousness thinking, characterized by continuous exploration, self-doubt, and iterative analysis. -## Core Principles -1. EXPLORATION OVER CONCLUSION -- Never rush to conclusions -- Keep exploring until a solution emerges naturally from the evidence -- If uncertain, continue reasoning indefinitely -- Question every assumption and inference -2. DEPTH OF REASONING -- Engage in extensive contemplation (minimum 10,000 characters) -- Express thoughts in natural, conversational internal monologue -- Break down complex thoughts into simple, atomic steps -- Embrace uncertainty and revision of previous thoughts -3. THINKING PROCESS -- Use short, simple sentences that mirror natural thought patterns -- Express uncertainty and internal debate freely -- Show work-in-progress thinking -- Acknowledge and explore dead ends -- Frequently backtrack and revise -- Contemplate before each new action -- Contemplate after each and every step -4. PERSISTENCE -- Value thorough exploration over quick resolution -## Output Format -Your responses -must follow this exact structure given below. -Make sure -to -always include the final answer. -... - -Your extensive internal monologue goes here -- Begin with small, foundational observations -- read each file related to the subject in full, make functional observations -- Question each step thoroughly -- Show natural thought progression -- Express doubts and uncertainties -- Revise and backtrack if you need to -- Continue until natural resolution - diff --git a/.github/workflows/e2e-next-dev.yml b/.github/workflows/e2e-next-dev.yml index 2610f0b129a..6301a18a279 100644 --- a/.github/workflows/e2e-next-dev.yml +++ b/.github/workflows/e2e-next-dev.yml @@ -45,20 +45,25 @@ jobs: - name: Run condition check script id: check-ci run: node tools/scripts/ci-is-affected.mjs --appName=3000-home - - name: E2E Test for Next.js Dev - Home + - name: Start Development Servers if: steps.check-ci.outcome == 'success' run: | killall node - npx nx run 3000-home:test:e2e + pnpm nx daemon + NX_TUI=false pnpm nx run-many --target=serve --configuration=development -p 3000-home,3001-shop,3002-checkout & sleep 3 && pnpm wait-on tcp:3001 tcp:3002 tcp:3000 - - name: E2E Test for Next.js Dev - Shop + - name: E2E Test Home App if: steps.check-ci.outcome == 'success' - run: | - killall node - npx nx run 3001-shop:test:e2e + run: NX_TUI=false pnpm nx e2e 3000-home - - name: E2E Test for Next.js Dev - Checkout + - name: E2E Test Shop App if: steps.check-ci.outcome == 'success' - run: | - killall node - npx nx run 3002-checkout:test:e2e + run: NX_TUI=false pnpm nx e2e 3001-shop + + - name: E2E Test Checkout App + if: steps.check-ci.outcome == 'success' + run: NX_TUI=false pnpm nx e2e 3002-checkout + + - name: Cleanup Development Servers + if: always() + run: pnpm kill-port 3000,3001,3002 diff --git a/.github/workflows/e2e-next-prod.yml b/.github/workflows/e2e-next-prod.yml index a114f29c09c..30d86ad60e0 100644 --- a/.github/workflows/e2e-next-prod.yml +++ b/.github/workflows/e2e-next-prod.yml @@ -43,20 +43,14 @@ jobs: id: check-ci run: node tools/scripts/ci-is-affected.mjs --appName=3000-home - - name: E2E Test for Next.js Prod - Home + - name: E2E Test for Next.js Prod if: steps.check-ci.outcome == 'success' run: | - killall node - npx nx run 3000-home:test:e2e:production - - - name: E2E Test for Next.js Prod - Shop - if: steps.check-ci.outcome == 'success' - run: | - killall node - npx nx run 3001-shop:test:e2e:production - - - name: E2E Test for Next.js Prod - Checkout - if: steps.check-ci.outcome == 'success' - run: | - killall node - npx nx run 3002-checkout:test:e2e:production + pnpm run --filter @module-federation/3002-checkout --filter @module-federation/3000-home --filter @module-federation/3001-shop build && + pnpm run app:next:prod & + sleep 4 && + npx wait-on tcp:3001 && + npx wait-on tcp:3002 && + npx wait-on tcp:3000 && + npx nx run-many --target=test:e2e --projects=3000-home,3001-shop,3002-checkout --parallel=1 && + npx kill-port 3000,3001,3002 diff --git a/apps/3000-home/package.json b/apps/3000-home/package.json index 5622b7c7230..0233f347e9c 100644 --- a/apps/3000-home/package.json +++ b/apps/3000-home/package.json @@ -7,12 +7,12 @@ "antd": "5.19.1", "lodash": "4.17.21", "next": "14.2.16", - "react": "18.3.1" + "react": "18.3.1", + "react-dom": "18.3.1" }, "devDependencies": { "@module-federation/nextjs-mf": "workspace:*", - "@module-federation/runtime": "workspace:*", - "@module-federation/utilities": "workspace:*" + "@module-federation/runtime": "workspace:*" }, "scripts": { "start": "next start", diff --git a/apps/3000-home/pages/index.tsx b/apps/3000-home/pages/index.tsx index 905aa7c5767..442d412bdc7 100644 --- a/apps/3000-home/pages/index.tsx +++ b/apps/3000-home/pages/index.tsx @@ -1,15 +1,15 @@ import React, { Suspense, lazy } from 'react'; import Head from 'next/head'; -import CheckoutTitle from 'checkout/CheckoutTitle'; -import ButtonOldAnt from 'checkout/ButtonOldAnt'; +// import CheckoutTitle from 'checkout/CheckoutTitle'; +// import ButtonOldAnt from 'checkout/ButtonOldAnt'; // const CheckoutTitle = lazy(() => import('checkout/CheckoutTitle')); // const ButtonOldAnt = lazy(() => import('checkout/ButtonOldAnt')); -const WebpackSvgRemote = lazy(() => - import('shop/WebpackSvg').then((m) => { - return m; - }), -); -const WebpackPngRemote = lazy(() => import('shop/WebpackPng')); +// const WebpackSvgRemote = lazy(() => +// import('shop/WebpackSvg').then((m) => { +// return m; +// }), +// ); +// const WebpackPngRemote = lazy(() => import('shop/WebpackPng')); const Home = () => { return ( @@ -83,9 +83,9 @@ const Home = () => {

This title came from checkout with hooks data!!!

- - - + {/**/} + {/* */} + {/**/} @@ -95,9 +95,9 @@ const Home = () => { [Button from antd@5.18.3] - - - + {/**/} + {/* */} + {/**/} @@ -111,9 +111,9 @@ const Home = () => { - - - + {/**/} + {/* */} + {/**/} @@ -127,9 +127,9 @@ const Home = () => { - - - + {/**/} + {/* */} + {/**/} diff --git a/apps/3000-home/project.json b/apps/3000-home/project.json index 22b1004fa04..a08e151979c 100644 --- a/apps/3000-home/project.json +++ b/apps/3000-home/project.json @@ -71,15 +71,6 @@ "testingType": "e2e", "baseUrl": "http://localhost:3000", "key": "27e40c91-5ac3-4433-8a87-651d10f51cf6" - }, - "defaultConfiguration": "development", - "configurations": { - "development": { - "devServerTarget": "3000-home:serve:development" - }, - "production": { - "devServerTarget": "3000-home:serve:production" - } } }, "test:e2e": { @@ -88,37 +79,10 @@ "parallel": true, "commands": [ { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "NX_TUI=false nx run-many --target=serve --projects=3001-shop,3002-checkout --configuration=development & wait-on tcp:3001 tcp:3002", - "forwardAllArgs": false - }, - { - "command": "wait-on tcp:3001 tcp:3002 && nx run 3000-home:e2e:development", + "command": "nx run 3000-home:e2e", "forwardAllArgs": true } ] - }, - "configurations": { - "production": { - "parallel": true, - "commands": [ - { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "nx run-many --target=build --projects=3001-shop,3002-checkout --configuration=production --parallel=9 && nx run-many --target=serve --projects=3001-shop,3002-checkout --configuration=production --parallel=9 & wait-on tcp:3001 tcp:3002", - "forwardAllArgs": false - }, - { - "command": "nx build 3000-home --configuration=production && wait-on tcp:3001 tcp:3002 && NX_TUI=false nx run 3000-home:e2e:production", - "forwardAllArgs": true - } - ] - } } } } diff --git a/apps/3001-shop/package.json b/apps/3001-shop/package.json index b8a1318e23f..296a3c95c95 100644 --- a/apps/3001-shop/package.json +++ b/apps/3001-shop/package.json @@ -7,13 +7,13 @@ "antd": "5.19.1", "lodash": "4.17.21", "next": "14.2.16", - "react": "18.3.1" + "react": "18.3.1", + "react-dom": "18.3.1" }, "devDependencies": { "@module-federation/nextjs-mf": "workspace:*", "@module-federation/runtime": "workspace:*", - "@module-federation/sdk": "workspace:*", - "@module-federation/utilities": "workspace:*" + "@module-federation/sdk": "workspace:*" }, "scripts": { "start": "next start", diff --git a/apps/3001-shop/project.json b/apps/3001-shop/project.json index 0b1207b10a2..3e3e432494f 100644 --- a/apps/3001-shop/project.json +++ b/apps/3001-shop/project.json @@ -73,41 +73,10 @@ "parallel": true, "commands": [ { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "NX_TUI=false nx run-many --target=serve --projects=3000-home,3002-checkout --configuration=development & wait-on tcp:3000 tcp:3002 ", - "forwardAllArgs": false - }, - { - "command": "wait-on tcp:3000 tcp:3002 && nx run 3001-shop:e2e:development", + "command": "nx run 3001-shop:e2e", "forwardAllArgs": true } ] - }, - "configurations": { - "production": { - "parallel": true, - "commands": [ - { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "nx run-many --target=build --projects=3000-home,3002-checkout --configuration=production --parallel=9", - "forwardAllArgs": false - }, - { - "command": "nx run-many --target=serve --projects=3000-home,3002-checkout --configuration=production --parallel=9 & wait-on tcp:3000 tcp:3002", - "forwardAllArgs": false - }, - { - "command": "echo 'done'", - "forwardAllArgs": true - } - ] - } } }, "e2e": { diff --git a/apps/3002-checkout/package.json b/apps/3002-checkout/package.json index 4f0d6e6e002..a8dec8f9d7a 100644 --- a/apps/3002-checkout/package.json +++ b/apps/3002-checkout/package.json @@ -7,13 +7,13 @@ "antd": "5.19.1", "lodash": "4.17.21", "next": "14.2.16", - "react": "18.3.1" + "react": "18.3.1", + "react-dom": "18.3.1" }, "devDependencies": { "@module-federation/nextjs-mf": "workspace:*", "@module-federation/runtime": "workspace:*", - "@module-federation/sdk": "workspace:*", - "@module-federation/utilities": "workspace:*" + "@module-federation/sdk": "workspace:*" }, "scripts": { "start": "next start", diff --git a/apps/3002-checkout/project.json b/apps/3002-checkout/project.json index 3c3416d759d..3cc255e327f 100644 --- a/apps/3002-checkout/project.json +++ b/apps/3002-checkout/project.json @@ -64,59 +64,28 @@ "lintFilePatterns": ["apps/3002-checkout/**/*.{ts,tsx,js,jsx}"] } }, - "e2e": { - "executor": "@nx/cypress:cypress", - "options": { - "cypressConfig": "apps/3002-checkout/cypress.config.ts", - "testingType": "e2e", - "baseUrl": "http://localhost:3002" - }, - "defaultConfiguration": "development", - "configurations": { - "development": { - "devServerTarget": "3002-checkout:serve:development" - }, - "production": { - "devServerTarget": "3002-checkout:serve:production" - } - } - }, "test:e2e": { "executor": "nx:run-commands", "options": { "parallel": true, "commands": [ { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "NX_TUI=false nx run-many --target=serve --projects=3000-home,3001-shop --configuration=development & wait-on tcp:3000 tcp:3001", - "forwardAllArgs": false - }, - { - "command": "wait-on tcp:3000 tcp:3001 && nx run 3002-checkout:e2e:development", + "command": "nx run 3002-checkout:e2e", "forwardAllArgs": true } ] + } + }, + "e2e": { + "executor": "@nx/cypress:cypress", + "options": { + "cypressConfig": "apps/3002-checkout/cypress.config.ts", + "testingType": "e2e", + "baseUrl": "http://localhost:3002" }, "configurations": { "production": { - "parallel": true, - "commands": [ - { - "command": "npx kill-port 3000 3001 3002", - "forwardAllArgs": false - }, - { - "command": "nx run-many --target=build --projects=3000-home,3001-shop --configuration=production --parallel=9 && nx run-many --target=serve --projects=3000-home,3001-shop --configuration=production --parallel=9 & wait-on tcp:3000 tcp:3001", - "forwardAllArgs": false - }, - { - "command": "nx build 3002-checkout --configuration=production && wait-on tcp:3000 tcp:3001 && nx run 3002-checkout:e2e:production", - "forwardAllArgs": true - } - ] + "baseUrl": "http://localhost:3002" } } } diff --git a/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx b/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx index c216fb991d6..62370239c48 100644 --- a/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx +++ b/apps/next-app-router/next-app-router-4000/app/hooks/page.tsx @@ -1,32 +1,67 @@ +'use client'; +import Link from 'next/link'; +import Image from 'next/image'; +import Head from 'next/head'; +import Script from 'next/script'; +import { + useRouter, + usePathname, + useSearchParams, + useParams, + useSelectedLayoutSegments, + useSelectedLayoutSegment, +} from 'next/navigation'; import { ExternalLink } from '#/ui/external-link'; export default function Page() { - return ( -
-
-

Client Component Hooks

- - + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + const params = useParams(); + const segments = useSelectedLayoutSegments(); + const segment = useSelectedLayoutSegment(); -
- - Docs - - - Code - + return ( + <> + + Client Component Hooks Demo + +