-
-
Notifications
You must be signed in to change notification settings - Fork 366
fix(enhanced): Populate buildMeta
and buildInfo
on ConsumeSharedPlugin
using fallbacks
#4038
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
fix(enhanced): Populate buildMeta
and buildInfo
on ConsumeSharedPlugin
using fallbacks
#4038
Conversation
|
buildMeta
and buildInfo
on ConsumeSharedModule
✅ Deploy Preview for module-federation-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
@@ -90,7 +90,6 @@ | |||
"type": "node", | |||
"request": "launch", | |||
"preLaunchTask": "pnpm-build-enhanced", | |||
"runtimeExecutable": "/Users/bytedance/.nvm/versions/node/v18.20.8/bin/node", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this hardcoded path really necessary?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probbably not
// We need to hook into the compilation process to copy metadata | ||
// after the fallback is fully built | ||
compilation.hooks.finishModules.tap('ConsumeSharedModule', () => { | ||
let dependency; | ||
|
||
if (this.options.eager) { | ||
// For eager mode, get the fallback directly | ||
dependency = this.dependencies[0]; | ||
} else { | ||
// For async mode, get it from the block | ||
dependency = this.blocks[0]?.dependencies[0]; | ||
} | ||
|
||
if (dependency) { | ||
const fallback = compilation.moduleGraph.getModule(dependency); | ||
if (fallback) { | ||
// Copy its buildMeta and buildInfo from fallback module | ||
this.buildMeta = { ...fallback.buildMeta }; | ||
this.buildInfo = { ...fallback.buildInfo }; | ||
} | ||
} | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following @ScriptedAlchemy hints 🙇, this is how I got buildMeta
to be properly populated. finishModules
seemed like the earliest hook to tap into, but there could be better ways of doing it. I'm open to any suggestions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost.
should not do this in the build method as it will cause massive hook registration per module built and rebuild, instead we should do it in the consume share plugin. Also compilation is not always guaranteed to be available in the build method of modules. For example when using loader.importModule or const plugin who evaluate macros, there is no compilation attached.
Ill push to this branch with the corrections for you to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! This all makes sense to me. I had a feeling registering in the plugin was the right approach - nowhere across the entire codebase we hook from within a Module, or anything other than a Plugin. I also overlooked the fact that we could
(modules, callback) => {
for (const module of modules) {
// Only process ConsumeSharedModule instances with fallback dependencies
if (
!(module instanceof ConsumeSharedModule) ||
!module.options.import
) {
continue;
}
Thanks for pushing. I will pull and test everything E2E and report back.
packages/enhanced/test/configCases/sharing/consume-nested/webpack.config.js
Show resolved
Hide resolved
...ges/enhanced/test/configCases/sharing/consume-nested/node_modules/package-1/esm/package.json
Outdated
Show resolved
Hide resolved
|
||
expect(module.dependencies.length).toBe(0); | ||
expect(module.blocks.length).toBe(0); | ||
}); | ||
|
||
it('should copy buildMeta and buildInfo from fallback', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since I had to update a few tests on this suite, I'm also adding this unit one to cover the new logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR fixes an issue in ConsumeSharedModule
where buildMeta
and buildInfo
properties were not properly populated during the build process, causing runtime errors in shared nested module scenarios with complex dependency structures.
Key Changes:
- Added logic to copy
buildMeta
andbuildInfo
from fallback modules toConsumeSharedModule
instances - Added comprehensive test coverage for the new metadata copying functionality
- Created integration test case for consume-nested scenarios
Reviewed Changes
Copilot reviewed 6 out of 11 changed files in this pull request and generated 3 comments.
File | Description |
---|---|
packages/enhanced/src/lib/sharing/ConsumeSharedModule.ts | Added hook to copy buildMeta and buildInfo from fallback modules after compilation finishes |
packages/enhanced/test/unit/sharing/ConsumeSharedModule.test.ts | Added unit tests and updated existing tests with proper mock compilation objects |
packages/enhanced/test/configCases/sharing/consume-nested/* | Added integration test case for nested module consumption scenarios |
.vscode/launch.json | Removed hardcoded runtime executable path |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
Co-authored-by: Copilot <[email protected]>
- Move buildMeta/buildInfo copying from ConsumeSharedModule to ConsumeSharedPlugin - Use finishModules.tapAsync with stage -10 (STAGE_BASIC) instead of seal hook - Ensure buildMeta is available before FlagDependencyExportsPlugin runs - Follow webpack's DelegatedModule pattern with spread operator copying - Add comprehensive test coverage for buildMeta copying functionality - Fix TypeScript errors in test files and improve type safety - Maintain ESM/CJS detection inheritance from fallback modules
…-at-webflow/fix-unpopulated-build-meta-and-info
@vinicius-at-webflow wanna give it a look now? |
@ScriptedAlchemy I pulled your commits locally and a bunch of moduleIdentifier = packages/enhanced/test/configCases/sharing/shared-strategy/App.js;
moduleName = ./App.js; loc = 4:31-36;
message = export 'default' (imported as 'React') was not found in 'react' (module has no exports); ![]() After some investigation I noticed it seemed to be a race condition and running at an earlier stage (-10) could be causing the problem. After bumping to 0 (with no success) and finally 10, the test suite was happy again, including the new But what's bothering me is that, per comments you left on the code, it should actually be running before |
buildMeta
and buildInfo
on ConsumeSharedModule
buildMeta
and buildInfo
on ConsumeSharedPlugin
using fallbacks
Removed outdated comments regarding buildMeta and buildInfo handling.
Ideally running it before flag dep exports plugin. However im guessing that that phase is actually whats responsible for setting metadata we need. Usually this is used for tree shaking. But if it needs to be stage 10 then no problem. |
@codex add changeset for this change |
For now, I can only help with PRs you've created. |
c62e2a8
into
module-federation:copy-build-meta
Description
ConsumeSharedModule
does not properly populate itsbuildMeta
andbuildInfo
properties during its build. This can cause critical issues inshared
nested module scenarios where packages have complex dependency structures with nestedpackage.json
files (with ESM"type": "module"
exports) as seen in #3779 with@mui/styled-engine
.Root cause
Bundlers rely on this metadata to understand
Module
characteristics such as module type detection (ESM vs CommonJS) andimport/export
statement generation. In the case ofwebpack
and@mui/styled-engine
, without the properbuildMeta
info, it generates incorrect import statements, leading to runtime errors like:Related Issue
#3779
Types of changes
Checklist