-
-
Notifications
You must be signed in to change notification settings - Fork 235
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
feat: add shareStrategy option #2870
Conversation
🦋 Changeset detectedLatest commit: d6c4b9a The changes in this PR will be included in the next version bump. This PR includes changesets to release 36 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for module-federation-docs ready!
To edit notification comments on pull requests, go to your Netlify site configuration. |
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.
Summary
This pull request introduces a new "shareStrategy" option to the Module Federation configuration across various packages. The main purpose is to provide more flexibility in how shared dependencies are handled between the host and remote applications in a federated setup.
The key changes include:
- Adding the "shareStrategy" option to the ModuleFederationPlugin configuration, allowing developers to specify the strategy for loading shared modules (version-first or loaded-first).
- Introducing the "shareStrategy" option to the NextFederationPlugin and the runtime plugin, enabling more control over the sharing behavior.
- Updating the "SharedHandler" class in the runtime package to accept the "shareStrategy" option, providing a more configurable way to initialize sharing.
- Adding a new "ShareStrategy" type to the runtime package, defining the available strategies for sharing dependencies.
These changes aim to improve the overall sharing strategy of federated applications, potentially optimizing the loading and usage of shared libraries. The new options allow developers to fine-tune the sharing behavior based on their specific requirements, leading to better performance and integration with the existing codebase.
File Summaries
File | Summary |
---|---|
packages/enhanced/src/lib/container/runtime/utils.ts | The code changes introduce a new 'shareStrategy' option to the 'normalizeRuntimeInitOptionsWithOutShared' function. This option allows for configuring the strategy used for sharing dependencies between the host and remote applications. |
packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts | The code changes add a new 'ShareStrategy' option to the ModuleFederationPlugin configuration. This new option allows developers to specify the strategy for loading shared modules, with two available options: 'version-first' and 'loaded-first'. |
packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts | The code changes introduce a new option called 'shareStrategy' to the NextFederationPlugin configuration. This option allows developers to specify the strategy for sharing dependencies between the host and remote applications in a federated module setup. |
packages/nextjs-mf/src/plugins/container/runtimePlugin.ts | The code changes introduce a new option called 'shareStrategy' to the 'shared' configuration in the 'runtimePlugin' module. This allows developers to specify the strategy for sharing dependencies, which can be useful for optimizing the loading and usage of shared libraries in a federated application. |
packages/runtime/src/shared/index.ts | The code changes introduce a new 'shareStrategy' option to the 'initializeSharing' method of the 'SharedHandler' class. This allows for more flexibility in how shared dependencies are handled, potentially improving the overall sharing strategy of the application. |
packages/runtime/src/type/config.ts | The code changes introduce a new 'ShareStrategy' type that can be set to either 'version-first' or 'loaded-first'. This new type is added to the 'Shared' object and a new 'shareStrategy' option is added to the 'Options' interface. These changes provide more flexibility in configuring the share strategy for the module federation runtime. |
packages/runtime/src/utils/share.ts | The code changes introduce a new 'shareStrategy' option to the 'formatShare' function, which is used to configure the sharing strategy for a shared module. This allows more flexibility in how shared modules are handled, potentially improving the overall sharing behavior of the application. |
packages/sdk/src/types/plugins/ModuleFederationPlugin.ts | The code changes introduce a new option called 'shareStrategy' to the ModuleFederationPluginOptions and SharedConfig interfaces. This new option allows developers to specify the strategy for loading shared modules, with the two available options being 'version-first' and 'loaded-first'. |
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.
Incremental Review
Comments posted: 15
Configuration
Squadron Mode: essential
Commits Reviewed
472e2cccd4b48d5246b945d342519f35ed6c42f8...d28d4af2738bad3c521070e3267eeaede8063efd
Files Reviewed
- packages/enhanced/src/lib/container/runtime/utils.ts
- packages/enhanced/src/schemas/container/ModuleFederationPlugin.ts
- packages/runtime/src/shared/index.ts
- packages/runtime/src/type/config.ts
- packages/runtime/src/utils/share.ts
- packages/sdk/src/types/plugins/ModuleFederationPlugin.ts
Files Ignored
These files were ignored due to the filter in the squadron.yaml file.
- .changeset/tasty-hotels-obey.md
- apps/runtime-demo/3005-runtime-host/webpack.config.js
- apps/runtime-demo/3006-runtime-remote/webpack.config.js
- apps/runtime-demo/3007-runtime-remote/webpack.config.js
shareStrategy: { | ||
$ref: '#/definitions/ShareStrategy', |
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.
The shareStrategy
property is referencing the ShareStrategy
definition, but it's nested within another object. This could lead to inconsistencies if the top-level shareStrategy
(line 772-774) is used differently. Consider unifying the usage of shareStrategy
across the schema to ensure consistency and prevent potential bugs.
For example, you could create a separate SharedItemConfig
type that includes shareStrategy
and reuse it in both places:
packages/runtime/src/utils/share.ts
Outdated
const arrayShareArgs = arrayOptions(shareArgs[pkgName]); | ||
res[pkgName] = res[pkgName] || []; | ||
arrayShareArgs.forEach((shareConfig) => { | ||
res[pkgName].push(formatShare(shareConfig, from, pkgName)); | ||
res[pkgName].push( | ||
formatShare(shareConfig, from, pkgName, userOptions.sharedStrategy), | ||
); | ||
}); | ||
return res; | ||
}, {} as ShareInfos); |
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 code block is performing multiple operations and could benefit from being split into smaller, more focused functions for better readability and maintainability. Consider refactoring it as follows:
const arrayShareArgs = arrayOptions(shareArgs[pkgName]); | |
res[pkgName] = res[pkgName] || []; | |
arrayShareArgs.forEach((shareConfig) => { | |
res[pkgName].push(formatShare(shareConfig, from, pkgName)); | |
res[pkgName].push( | |
formatShare(shareConfig, from, pkgName, userOptions.sharedStrategy), | |
); | |
}); | |
return res; | |
}, {} as ShareInfos); | |
export function processShareArgs(shareArgs: Record<string, ShareArgs | ShareArgs[]>, from: string, userOptions: UserOptions): ShareInfos { | |
return Object.entries(shareArgs).reduce((res, [pkgName, args]) => { | |
res[pkgName] = processPackageShareArgs(args, from, pkgName, userOptions.sharedStrategy); | |
return res; | |
}, {} as ShareInfos); | |
} | |
function processPackageShareArgs(args: ShareArgs | ShareArgs[], from: string, pkgName: string, sharedStrategy?: ShareStrategy): Shared[] { | |
return arrayOptions(args).map(shareConfig => | |
formatShare(shareConfig, from, pkgName, sharedStrategy) | |
); | |
} | |
const shareInfos = processShareArgs(shareArgs, from, userOptions); |
This refactoring improves readability and makes the code more modular, allowing for easier testing and maintenance.
packages/runtime/src/utils/share.ts
Outdated
shareArgs: ShareArgs, | ||
from: string, | ||
name: string, | ||
sharedStrategy?: ShareStrategy, | ||
): Shared { | ||
let get: Shared['get']; | ||
if ('get' in shareArgs) { |
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.
The function formatShare
is handling multiple responsibilities and could benefit from being split into smaller, more focused functions. Consider refactoring it to improve readability and maintainability:
shareArgs: ShareArgs, | |
from: string, | |
name: string, | |
sharedStrategy?: ShareStrategy, | |
): Shared { | |
let get: Shared['get']; | |
if ('get' in shareArgs) { | |
export function formatShare( | |
shareArgs: ShareArgs, | |
from: string, | |
name: string, | |
sharedStrategy?: ShareStrategy, | |
): Shared { | |
const get = determineGetter(shareArgs, name); | |
const scope = determineScope(shareArgs.scope); | |
const strategy = determineStrategy(shareArgs.strategy, sharedStrategy); | |
return { | |
deps: [], | |
useIn: [], | |
from, | |
loading: null, | |
...shareArgs, | |
shareConfig: formatShareConfig(shareArgs), | |
get, | |
loaded: determineLoaded(shareArgs), | |
version: shareArgs.version ?? '0', | |
scope, | |
strategy, | |
}; | |
} | |
function determineGetter(shareArgs: ShareArgs, name: string): Shared['get'] { | |
if ('get' in shareArgs) return shareArgs.get; | |
if ('lib' in shareArgs) return () => Promise.resolve(shareArgs.lib); | |
return () => Promise.resolve(() => { | |
throw new Error(`Can not get shared '${name}'!`); | |
}); | |
} | |
function determineScope(scope?: string | string[]): string[] { | |
return Array.isArray(scope) ? scope : [scope ?? 'default']; | |
} | |
function determineStrategy(argStrategy?: ShareStrategy, sharedStrategy?: ShareStrategy): ShareStrategy { | |
return (argStrategy ?? sharedStrategy) || 'version-first'; | |
} | |
function formatShareConfig(shareArgs: ShareArgs): SharedConfig { | |
return { | |
requiredVersion: `^${shareArgs.version}`, | |
singleton: false, | |
eager: false, | |
strictVersion: false, | |
...shareArgs.shareConfig, | |
}; | |
} | |
function determineLoaded(shareArgs: ShareArgs): boolean | undefined { | |
return shareArgs?.loaded || 'lib' in shareArgs ? true : undefined; | |
} |
This refactoring breaks down the formatShare
function into smaller, more focused functions, improving readability and making the code easier to maintain and test.
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.
Incremental Review
Comments posted: 2
Configuration
Squadron Mode: essential
Commits Reviewed
2a065424f6c7eef2fa9f95ed33234da388d367fb...d9b2c3793428f3da2d6ce1d1c19ae51c8b36930b
Files Reviewed
- packages/enhanced/src/lib/container/runtime/utils.ts
Files Ignored
These files were ignored due to the filter in the squadron.yaml file.
- packages/enhanced/test/configCases/sharing/shared-strategy/App.js
- packages/enhanced/test/configCases/sharing/shared-strategy/index.js
- packages/enhanced/test/configCases/sharing/shared-strategy/node_modules/react.js
- packages/enhanced/test/configCases/sharing/shared-strategy/package.json
- packages/enhanced/test/configCases/sharing/shared-strategy/webpack.config.js
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.
Incremental Review
Comments posted: 4
Configuration
Squadron Mode: essential
Commits Reviewed
d9b2c3793428f3da2d6ce1d1c19ae51c8b36930b...7013a7097a3d478eed48de2baac413d9d0306fde
Files Reviewed
- packages/nextjs-mf/src/plugins/NextFederationPlugin/index.ts
- packages/nextjs-mf/src/plugins/container/runtimePlugin.ts
false
|
||
控制共享依赖的加载策略: | ||
|
||
- `'version-first'`:版本优先。设置后,会自动加载所有 *remotes* 入口文件,并**注册**对应的共享依赖,确保能获取到所有的共享依赖版本。当对版本有严格要求时,推荐使用此策略。 |
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.
version-first 主要是能够保证使用最高的版本,loaded-first 是谁先加载用谁的,这个没有体现出来
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.
更新了描述:
-
'version-first'
:版本优先,确保使用最高版本的共享依赖。设置后,会自动加载所有 remotes 入口文件,并注册对应的共享依赖,确保能获取到所有的共享依赖版本。当对版本有严格要求时,推荐使用此策略。 -
'loaded-first'
:复用优先,大幅减少多余的依赖请求。设置后,不会自动加载 remotes 入口文件(仅在有需求时才会加载),优先复用已加载的共享依赖。当对版本没有严格要求且对性能有要求时,推荐使用此策略。
Description
rspack pr: web-infra-dev/rspack#7651
Related Issue
Types of changes
Checklist