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: exclude version ranges from federation #17425

Open
wants to merge 50 commits into
base: main
Choose a base branch
from

Conversation

tmpaul
Copy link

@tmpaul tmpaul commented Jun 26, 2023

Summary

🤖 Generated by Copilot at 4a3cc04

No summary available (Limit exceeded: required to process 50446 tokens, but only 50000 are allowed per call)

Details

🤖 Generated by Copilot at 4a3cc04

  • Add a new feature to allow excluding modules or version ranges from sharing based on the exclusion criteria (link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link, link)
  • Define the SharedExclusionCriteria type and schema, which has a version property that represents a version or semver range of the dependency to exclude from sharing (link, link, link, link, link, link)
  • Add the exclusionCriteria property to the SharedConfig type and schema, which references the SharedExclusionCriteria type and schema (link, link, link, link, link)
  • Add the exclusionCriteria property to the config object and the item object for the ConsumeSharedPlugin and the ProvideSharedPlugin (link, link, link, link, link, link)
  • Add the fallbackVersion property to the exclusionCriteria property for the ConsumeSharedPlugin, which is set to the version property of the config object if it exists (link, link)
  • Add the path, semver, and utils modules as dependencies for the ConsumeSharedPlugin and the ProvideSharedPlugin (link, link, link, link, link)
  • Add the validateShareOptions function to the utils module, which performs additional validation logic for the share options and throws an error if any of the options have both exclusionCriteria and singleton set to true (link)
  • Add the exclusionCriteria property to the ConsumeSharedFallbackDependency class, which holds the criteria used to exclude modules or version ranges from sharing for the dependency (link)
  • Add a variable declaration for the consumedModule, which is an instance of the ConsumeSharedModule class, representing a module that consumes a shared module (link)
  • Add a block of code that checks if the exclusionCriteria is provided for the consumedModule, and if so, performs a check against the resolved import and the fallback version to determine if the consumption should be excluded (link)
  • Add a block of code that checks if the exclusionCriteria is provided for the shared module in the ProvideSharedPlugin, and if so, performs a check against the version of the module using the satisfy and parseRange functions from the semver module (link)
  • Add a call to the validateShareOptions function in the SharePlugin, passing the sharedOptions array, which contains the options for each shared module (link)
  • Update the generated code for the schema validation files for the ModuleFederationPlugin, the ConsumeSharedPlugin, the ProvideSharedPlugin, and the SharePlugin to reflect the changes in the JSON schema files (link, link, link, link)
  • Add test cases for the new feature of excluding modules from sharing based on the exclusion criteria (link, link, link, link, link, link)
    • Add a test case in test/configCases/container/container-exclude-sharing to test the feature with the ModuleFederationPlugin (link, link, link, link)
    • Add a test case in test/configCases/sharing/consume-module to test the feature with the SharePlugin (link, link)

First PR based on the discussion here: #17404 (comment)

New property exclusionCriteria

This new property is a object that in the current PR accepts a version range object using the version property.

The following logic is used for excluding a module/package from sharing

ProvideSharedPlugin

  1. Check if exclusionCriteria.version is defined.
  2. If yes, check if version is defined. If version is not provided, attempt to find version from closest package.json.
  3. Check if version satisfies the exclusion range. If yes, exclude, else include.

ConsumeSharedPlugin

This plugin is more involved since there is no "inherent" version, but there is only requiredVersion. While it is possible to do range intersection of requiredVersion and exclusionCriteria.version, the current semver util lib in webpack makes this difficult to do. Instead, we pass the version property from ModuleFederationPlugin as exclusionCriteria.fallbackVersion, and use that version to check. If this property is missing, use the nearest package.json file corresponding to the resolved import.

If neither conditions match, it will be shared.

I've added inline comments to the PR to explain what I'm doing. Open to feedback/suggestions, thank you.

tmpaul and others added 30 commits June 21, 2023 00:34
Bumps [eslint-plugin-jest](https://github.com/jest-community/eslint-plugin-jest) from 27.2.1 to 27.2.2.
- [Release notes](https://github.com/jest-community/eslint-plugin-jest/releases)
- [Changelog](https://github.com/jest-community/eslint-plugin-jest/blob/main/CHANGELOG.md)
- [Commits](jest-community/eslint-plugin-jest@v27.2.1...v27.2.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-jest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <[email protected]>
@webpack-bot
Copy link
Contributor

For maintainers only:

  • This needs to be documented (issue in webpack/webpack.js.org will be filed when merged)
  • This needs to be backported to webpack 4 (issue will be created when merged)

/**
* Version of the package provided by the fallback if there is one.
*/
fallbackVersion?: string;
Copy link
Author

Choose a reason for hiding this comment

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

Adds a new property called fallbackVersion, which is only exposed to ConsumeSharedPlugin. It is not directly accessible to ModuleFederationPlugin consumers. The value of this property is the truthy value of version property passed to ModuleFederationPlugin.

// Without a resolved import, we cannot proceed with exclusion check
if (!importResolved) {
return consumedModule;
}
Copy link
Author

Choose a reason for hiding this comment

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

Here, we check if importResolved can be mapped out. If there is no resolved import path for a request, we cannot decide whether to exclude it from sharing, so by default include it.

config.exclusionCriteria.fallbackVersion
)
) {
return undefined;
Copy link
Author

Choose a reason for hiding this comment

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

If user has supplied a version property to ModuleFed plugin, use that to check against the exclusionCriteria.version range

// not exist in the package.json file, then we use the "version" property
// set by users in the share config, which is passed here as fallbackVersion
// a.k.a the version used to register the package in the scope.
getDescriptionFile(
Copy link
Author

Choose a reason for hiding this comment

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

Find the closest package.json for the resolved import. This gives us the version of the package/module that corresponds to the request. Note that there are shared modules that do not have a corresponding package.json file, and for these, we do not exclude them from sharing unless the user supplies a version property. If that is the case, the check in line 269 will activate

!data ||
(data && !data.version) ||
(data && data.name !== request)
) {
Copy link
Author

Choose a reason for hiding this comment

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

Check that the package.json name matches the requested module. Otherwise it can resolve to the root package.json of the project.

...options.exclusionCriteria,
fallbackVersion: options.version ? options.version : undefined
}
: undefined,
Copy link
Author

Choose a reason for hiding this comment

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

Pass in version as fallbackVersion to exclusionCriteria. As far a consumed module is concerned, the version property represents the version of the fallback.

Merge branch 'main' of github.com:tmpaul/webpack into feat/version-exclude
@tmpaul
Copy link
Author

tmpaul commented Jul 2, 2023

@alexander-akait Friendly bump

@alexander-akait
Copy link
Member

@tmpaul Sorry for long delay (long store), is it still valid?

@tmpaul
Copy link
Author

tmpaul commented Jan 23, 2024

@tmpaul Sorry for long delay (long store), is it still valid?

@alexander-akait Yes. Due to the time gap, I assumed that it would not be reviewed. I have merged the latest changes. Please take a look when you can

@alexander-akait
Copy link
Member

@ScriptedAlchemy Hello, what do you think about this PR?

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.

7 participants