Skip to content
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

Merged
merged 9 commits into from
Aug 22, 2024
Merged

feat: add shareStrategy option #2870

merged 9 commits into from
Aug 22, 2024

Conversation

2heal1
Copy link
Member

@2heal1 2heal1 commented Aug 21, 2024

Description

  • Add shareStrategy option in build plugin and runtime option
  • Deprecate share.strategy option

rspack pr: web-infra-dev/rspack#7651

Related Issue

Types of changes

  • Docs change / refactoring / dependency upgrade
  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have updated the documentation.

Copy link

changeset-bot bot commented Aug 21, 2024

🦋 Changeset detected

Latest commit: d6c4b9a

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 36 packages
Name Type
@module-federation/enhanced Patch
@module-federation/runtime Patch
@module-federation/sdk Patch
@module-federation/modern-js Patch
@module-federation/nextjs-mf Patch
@module-federation/node Patch
3008-runtime-remote Patch
host Patch
host-v5 Patch
host-vue3 Patch
remote1 Patch
remote2 Patch
remote3 Patch
remote4 Patch
@module-federation/modernjs Patch
@module-federation/devtools Patch
@module-federation/dts-plugin Patch
@module-federation/runtime-tools Patch
@module-federation/webpack-bundler-runtime Patch
@module-federation/esbuild Patch
@module-federation/managers Patch
@module-federation/manifest Patch
@module-federation/rspack Patch
@module-federation/utilities Patch
@module-federation/bridge-react-webpack-plugin Patch
modernjs-ssr-dynamic-nested-remote Patch
modernjs-ssr-dynamic-remote-new-version Patch
modernjs-ssr-dynamic-remote Patch
modernjs-ssr-host Patch
modernjs-ssr-nested-remote Patch
modernjs-ssr-remote-new-version Patch
modernjs-ssr-remote Patch
@module-federation/third-party-dts-extractor Patch
@module-federation/bridge-react Patch
@module-federation/bridge-vue3 Patch
@module-federation/bridge-shared Patch

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

Copy link

netlify bot commented Aug 21, 2024

Deploy Preview for module-federation-docs ready!

Name Link
🔨 Latest commit d6c4b9a
🔍 Latest deploy log https://app.netlify.com/sites/module-federation-docs/deploys/66c6e5f1512af50008dc7a85
😎 Deploy Preview https://deploy-preview-2870--module-federation-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

@squadronai squadronai bot left a 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:

  1. Adding the "shareStrategy" option to the ModuleFederationPlugin configuration, allowing developers to specify the strategy for loading shared modules (version-first or loaded-first).
  2. Introducing the "shareStrategy" option to the NextFederationPlugin and the runtime plugin, enabling more control over the sharing behavior.
  3. Updating the "SharedHandler" class in the runtime package to accept the "shareStrategy" option, providing a more configurable way to initialize sharing.
  4. 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'.

Copy link
Contributor

@squadronai squadronai bot left a 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

packages/enhanced/src/lib/container/runtime/utils.ts Outdated Show resolved Hide resolved
Comment on lines +470 to +471
shareStrategy: {
$ref: '#/definitions/ShareStrategy',
Copy link
Contributor

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:

Comment on lines 68 to 76
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);
Copy link
Contributor

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:

Suggested change
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.

Comment on lines 20 to 26
shareArgs: ShareArgs,
from: string,
name: string,
sharedStrategy?: ShareStrategy,
): Shared {
let get: Shared['get'];
if ('get' in shareArgs) {
Copy link
Contributor

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:

Suggested change
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.

Copy link
Contributor

@squadronai squadronai bot left a 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

packages/enhanced/src/lib/container/runtime/utils.ts Outdated Show resolved Hide resolved
packages/enhanced/src/lib/container/runtime/utils.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@squadronai squadronai bot left a 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

@2heal1 2heal1 changed the title WIP: feat: add shareStrategy option feat: add shareStrategy option Aug 22, 2024

控制共享依赖的加载策略:

- `'version-first'`:版本优先。设置后,会自动加载所有 *remotes* 入口文件,并**注册**对应的共享依赖,确保能获取到所有的共享依赖版本。当对版本有严格要求时,推荐使用此策略。
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

version-first 主要是能够保证使用最高的版本,loaded-first 是谁先加载用谁的,这个没有体现出来

Copy link
Member Author

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 入口文件(仅在有需求时才会加载),优先复用已加载的共享依赖。当对版本没有严格要求且对性能有要求时,推荐使用此策略。

@zhoushaw zhoushaw merged commit b90fa7d into main Aug 22, 2024
16 checks passed
@zhoushaw zhoushaw deleted the feat/shared-strategy branch August 22, 2024 08:45
@2heal1 2heal1 mentioned this pull request Aug 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants