- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 307
perf: add tree shake markers to enable/disable capabilities to reduce bundle size #3704
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
Changes from all commits
3bcd4b2
f9b5ed9
430cf40
87d2bf3
65dff8e
0d21411
9c8d93e
4ba61af
79094cd
eb01df9
03cb017
1ff85e9
5bbcca6
be54b58
0dd1d3a
ea05c2c
64ea9c1
08ae524
da7809b
e45311b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
--- | ||
"@module-federation/enhanced": patch | ||
--- | ||
|
||
Updated ModuleFederationPlugin to enhance configuration capabilities and target environment identification. | ||
|
||
- Introduced `definePluginOptions` to manage DefinePlugin settings. | ||
- Added `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` to handle disabling of snapshot optimizations via experiments. | ||
- Implemented environment target detection (`web` or `node`) based on compiler options and experiments. | ||
- Consolidated DefinePlugin application with the newly constructed `definePluginOptions`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
"@module-federation/sdk": patch | ||
--- | ||
|
||
Introduced environment-specific handling for `createScriptNode` and `loadScriptNode` functions and added build optimization options. | ||
|
||
- Declared `ENV_TARGET` constant to differentiate between 'web' and 'node' environments. | ||
- Modified `createScriptNode` and `loadScriptNode` to execute only in Node.js environment. | ||
- Throws an error if attempted in a non-Node.js environment. | ||
- Added logging for debugging purposes. | ||
- Introduced `optimization` options in `ModuleFederationPluginOptions`. | ||
- Added config for `disableSnapshot` and `target` environment optimizations. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
"@module-federation/runtime-core": patch | ||
--- | ||
|
||
Add conditional functionality for snapshots and optimize entry loading. | ||
|
||
- Introduced FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN constant to control snapshot functionality. | ||
- Default to include snapshot functionality if constant is not defined. | ||
- Simplified plugin loading logic to check USE_SNAPSHOT flag. | ||
- Added ENV_TARGET constant to differentiate between web and node environments. | ||
- Extracted duplicated logic for handling remote entry loaded into `handleRemoteEntryLoaded` function. | ||
- Refactored entry loading to use conditional environment checks with `ENV_TARGET`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
--- | ||
"@module-federation/rspack": patch | ||
--- | ||
|
||
Update Rspack ModuleFederationPlugin to support enhanced configuration capabilities and environment targeting. | ||
|
||
- Injects `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` and `ENV_TARGET` as global constants using DefinePlugin, based on the new `experiments.optimization` options. | ||
- Ensures parity with the Webpack plugin for build-time optimizations and environment-specific code paths. | ||
- Enables tree-shaking and feature toggling in the runtime and SDK for both Rspack and Webpack builds. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,11 @@ new ModuleFederationPlugin({ | |
experiments: { | ||
asyncStartup: true, | ||
externalRuntime: false, | ||
provideExternalRuntime: false | ||
provideExternalRuntime: false, | ||
optimization: { | ||
disableSnapshot: false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks better to change it to "disable manifest" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It also includes the inability to use the ts type There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes but there are many users who come from webpack v1 - they want direct switch to v2 and dont use any new capability - first introduction to v2 is a v70kb increase in entry file - and many companies took advantage of small remote entry size of v1 where its like 10kb, they will load 80+ remote modules, but now they are 7X larger and remoteEntry becomes 5.7mb of eager chunk loading required to initialize the system. So these users would prefer to turn off features they do not yet adopt, then explore wha they need and slowly increase the payload size while communicating the values of the additional runtime code. Or if user is in production - they may want no json http call and prefer js entry with minimal payload overhead, so they can use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. any user not using json protocol has no ts sync already. So if user only uses js remote they already are on ~v1.5 level capabilities. So they have no requirement for the code and already do not leverage all of v2 features. Some user wants v1 + runtime plugin. to keep payload cost of adoption small but valuable to busniess case. |
||
target: 'web', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this designed for other bundler like vite ? Becasue we can infer it from automatically. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the future, will it automatically be apply in webpack/rspack ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not designed for other bundler - but i was worried about automatic inference because case like web worker or custom react native target, the infer target may not always be accurate - and you end up removing part of the system from a environment acting like another. Like in react native or lynx - it use commonjs chunk loader - but may be target of web worker or worker, so this may compile to web target but use other mechanics and assuming that may have breaking implications. Yes we can detect, but custom environment or mixed output could exist that i dont foresee right now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes the feature will work in webpack and rspack, but currently user must opt into it explicitly - so if there is problem, they understand why because they enabled it. We could add a 'auto' option where we add attempt to infer, so user still must use flag to enable and we can add other enums to it if needed like react-native for custom env target code that we may need to support within the runtime core - without making the core larger - and if user want to tree shake the vanillia runtime themselves - they can just set these in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gotcha cool |
||
}, | ||
}, | ||
shared: { | ||
react: { | ||
|
@@ -59,3 +63,40 @@ Make sure to only configure it on the topmost consumer! If multiple consumers in | |
::: | ||
|
||
Setting `true` will inject the MF runtime at the consumer. | ||
|
||
## optimization | ||
|
||
This object contains flags related to build-time optimizations that can affect the Module Federation runtime's size and behavior. | ||
|
||
### disableSnapshot | ||
|
||
- Type: `boolean` | ||
- Required: No | ||
- Default: `false` | ||
|
||
When set to `true`, this option defines the `FEDERATION_OPTIMIZE_NO_SNAPSHOT_PLUGIN` global constant as `true` during the build. In the `@module-federation/runtime-core`, this prevents the `snapshotPlugin()` and `generatePreloadAssetsPlugin()` from being included and initialized within the FederationHost. | ||
|
||
**Impact:** | ||
* **Benefit:** Can reduce the overall bundle size of the Module Federation runtime by excluding the code for these two plugins. | ||
* **Cost:** Disables the functionality provided by these plugins. The `snapshotPlugin` is crucial for the "mf-manifest protocol" – it's responsible for generating or providing runtime access to a build manifest (e.g., `mf-manifest.json`) containing metadata about exposed modules, shared dependencies, versions, and remotes. Disabling it means: | ||
* The runtime loses access to this build manifest data. | ||
* Features relying on the manifest, such as dynamic remote discovery, manifest-based version compatibility checks, advanced asset preloading (also handled by the removed `generatePreloadAssetsPlugin`), and potentially runtime debugging/introspection tools, will not function correctly or will be unavailable. | ||
* Use this option only if you do not rely on these manifest-driven features and prioritize a minimal runtime footprint. | ||
|
||
### target | ||
|
||
- Type: `'web' | 'node'` | ||
- Required: No | ||
- Default: Inferred from Webpack's `target` option (usually `'web'`) | ||
|
||
This option defines the `ENV_TARGET` global constant during the build, specifying the intended execution environment. | ||
|
||
**Impact:** | ||
* **`target: 'web'`**: Optimizes the build for browser environments. | ||
* Ensures browser-specific remote entry loading mechanisms are used (`loadEntryDom`). | ||
* Crucially, enables tree-shaking/dead-code elimination for Node.js-specific code within the `@module-federation/sdk`. Functions like `createScriptNode` and `loadScriptNode`, along with their required Node.js built-in modules (e.g., `vm`, `path`, `http`), are completely removed from the bundle, significantly reducing its size. | ||
* **`target: 'node'`**: Optimizes the build for Node.js environments. | ||
* Ensures Node.js-specific remote entry loading mechanisms are used (`loadEntryNode`). | ||
* Includes the necessary Node.js-specific functions from the SDK (`createScriptNode`, `loadScriptNode`) in the bundle, allowing the federated application to function correctly in Node.js. | ||
|
||
Explicitly setting this value is recommended to ensure the intended optimizations are applied, especially in universal or server-side rendering scenarios. |
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.
This format changeset can not be consumed . need to fix https://github.com/module-federation/core/actions/runs/15035515868/job/42256409157
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.
fixed there was ``` in another file that broke it