mirror of https://github.com/webpack/webpack.git
Merge branch 'master' into exports-field
# Conflicts: # lib/container/OverridablesPlugin.js
This commit is contained in:
commit
57bd6ed348
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be exposed by this container. When provided, property name is used as public name, otherwise public name is automatically inferred from request.
|
||||
*/
|
||||
export type Exposes = (ExposesItem | ExposesObject)[] | ExposesObject;
|
||||
/**
|
||||
* Module that should be exposed by this container.
|
||||
*/
|
||||
export type ExposesItem = string;
|
||||
/**
|
||||
* Modules that should be exposed by this container.
|
||||
*/
|
||||
export type ExposesItems = ExposesItem[];
|
||||
/**
|
||||
* Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.
|
||||
*/
|
||||
export type Remotes = (RemotesItem | RemotesObject)[] | RemotesObject;
|
||||
/**
|
||||
* Container location from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export type RemotesItem = string;
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export type RemotesItems = RemotesItem[];
|
||||
|
||||
export interface _Container {
|
||||
[k: string]: any;
|
||||
}
|
||||
/**
|
||||
* Modules that should be exposed by this container. Property names are used as public paths.
|
||||
*/
|
||||
export interface ExposesObject {
|
||||
/**
|
||||
* Modules that should be exposed by this container.
|
||||
*/
|
||||
[k: string]: ExposesConfig | ExposesItem | ExposesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be exposed by this container.
|
||||
*/
|
||||
export interface ExposesConfig {
|
||||
/**
|
||||
* Request to a module that should be exposed by this container.
|
||||
*/
|
||||
import: ExposesItem | ExposesItems;
|
||||
}
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.
|
||||
*/
|
||||
export interface RemotesObject {
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
[k: string]: RemotesConfig | RemotesItem | RemotesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export interface RemotesConfig {
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
external: RemotesItem | RemotesItems;
|
||||
/**
|
||||
* The name of the share scope shared with this remote.
|
||||
*/
|
||||
shareScope?: string;
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be exposed by this container. When provided, property name is used as public name, otherwise public name is automatically inferred from request.
|
||||
*/
|
||||
export type Exposes = (ExposesItem | ExposesObject)[] | ExposesObject;
|
||||
/**
|
||||
* Module that should be exposed by this container.
|
||||
*/
|
||||
export type ExposesItem = string;
|
||||
/**
|
||||
* Modules that should be exposed by this container.
|
||||
*/
|
||||
export type ExposesItems = ExposesItem[];
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overridables =
|
||||
| (OverridablesItem | OverridablesObject)[]
|
||||
| OverridablesObject;
|
||||
/**
|
||||
* Request to a module in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItem = string;
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItems = OverridablesItem[];
|
||||
/**
|
||||
* Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overrides = (OverridesItem | OverridesObject)[] | OverridesObject;
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export type OverridesItem = string;
|
||||
/**
|
||||
* Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.
|
||||
*/
|
||||
export type Remotes = (RemotesItem | RemotesObject)[] | RemotesObject;
|
||||
/**
|
||||
* Container location from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export type RemotesItem = string;
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export type RemotesItems = RemotesItem[];
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host. When provided, property name is used as shared key, otherwise shared key is automatically inferred from request.
|
||||
*/
|
||||
export type Shared = (SharedItem | SharedObject)[] | SharedObject;
|
||||
/**
|
||||
* Module that should be shared with remotes and/or host.
|
||||
*/
|
||||
export type SharedItem = string;
|
||||
|
||||
export interface _SharedContainer {
|
||||
[k: string]: any;
|
||||
}
|
||||
/**
|
||||
* Modules that should be exposed by this container. Property names are used as public paths.
|
||||
*/
|
||||
export interface ExposesObject {
|
||||
/**
|
||||
* Modules that should be exposed by this container.
|
||||
*/
|
||||
[k: string]: ExposesConfig | ExposesItem | ExposesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be exposed by this container.
|
||||
*/
|
||||
export interface ExposesConfig {
|
||||
/**
|
||||
* Request to a module that should be exposed by this container.
|
||||
*/
|
||||
import: ExposesItem | ExposesItems;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridablesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
[k: string]: OverridablesConfig | OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export interface OverridablesConfig {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
import: OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
[k: string]: OverridesConfig | OverridesItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export interface OverridesConfig {
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
import: OverridesItem;
|
||||
}
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.
|
||||
*/
|
||||
export interface RemotesObject {
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
[k: string]: RemotesConfig | RemotesItem | RemotesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
export interface RemotesConfig {
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
external: RemotesItem | RemotesItems;
|
||||
}
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host. Property names are used as shared keys.
|
||||
*/
|
||||
export interface SharedObject {
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host.
|
||||
*/
|
||||
[k: string]: SharedConfig | SharedItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be shared with remotes and/or host.
|
||||
*/
|
||||
export interface SharedConfig {
|
||||
/**
|
||||
* Module that should be shared with remotes and/or host.
|
||||
*/
|
||||
import: SharedItem;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
export type Shared = (SharedItem | SharedObject)[] | SharedObject;
|
||||
/**
|
||||
* A module that should be shared in the share scope.
|
||||
*/
|
||||
export type SharedItem = string;
|
||||
/**
|
||||
* Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.
|
||||
*/
|
||||
export type SharedVersionArray = (number | string)[];
|
||||
|
||||
export interface _Sharing {
|
||||
[k: string]: any;
|
||||
}
|
||||
/**
|
||||
* Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.
|
||||
*/
|
||||
export interface SharedObject {
|
||||
/**
|
||||
* Modules that should be shared in the share scope.
|
||||
*/
|
||||
[k: string]: SharedConfig | SharedItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be shared in the share scope.
|
||||
*/
|
||||
export interface SharedConfig {
|
||||
/**
|
||||
* Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.
|
||||
*/
|
||||
eager?: boolean;
|
||||
/**
|
||||
* Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.
|
||||
*/
|
||||
import?: false | SharedItem;
|
||||
/**
|
||||
* Version requirement from module in share scope.
|
||||
*/
|
||||
requiredVersion?: string | SharedVersionArray;
|
||||
/**
|
||||
* Module is looked up under this key from the share scope.
|
||||
*/
|
||||
shareKey?: string;
|
||||
/**
|
||||
* Share scope name.
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Allow only a single version of the shared module in share scope (disabled by default).
|
||||
*/
|
||||
singleton?: boolean;
|
||||
/**
|
||||
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
|
||||
*/
|
||||
strictVersion?: boolean;
|
||||
/**
|
||||
* Version of the provided module. Will replace lower matching versions, but not higher.
|
||||
*/
|
||||
version?: false | string | SharedVersionArray;
|
||||
}
|
||||
|
|
@ -52,20 +52,6 @@ export type LibraryType =
|
|||
* If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module.
|
||||
*/
|
||||
export type UmdNamedDefine = boolean;
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overridables =
|
||||
| (OverridablesItem | OverridablesObject)[]
|
||||
| OverridablesObject;
|
||||
/**
|
||||
* Request to a module in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItem = string;
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItems = OverridablesItem[];
|
||||
|
||||
export interface ContainerPluginOptions {
|
||||
/**
|
||||
|
|
@ -85,9 +71,9 @@ export interface ContainerPluginOptions {
|
|||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
* The name of the share scope which is shared with the host (defaults to 'default').
|
||||
*/
|
||||
overridables?: Overridables;
|
||||
shareScope?: string;
|
||||
}
|
||||
/**
|
||||
* Modules that should be exposed by this container. Property names are used as public paths.
|
||||
|
|
@ -170,21 +156,3 @@ export interface LibraryCustomUmdObject {
|
|||
*/
|
||||
root?: string[] | string;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridablesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
[k: string]: OverridablesConfig | OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export interface OverridablesConfig {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
import: OverridablesItem | OverridablesItems;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,14 +4,6 @@
|
|||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overrides = (OverridesItem | OverridesObject)[] | OverridesObject;
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export type OverridesItem = string;
|
||||
/**
|
||||
* Specifies the default type of externals ('amd*', 'umd*', 'system' and 'jsonp' depend on output.libraryTarget set to the same value).
|
||||
*/
|
||||
|
|
@ -48,10 +40,6 @@ export type RemotesItem = string;
|
|||
export type RemotesItems = RemotesItem[];
|
||||
|
||||
export interface ContainerReferencePluginOptions {
|
||||
/**
|
||||
* Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
overrides?: Overrides;
|
||||
/**
|
||||
* The external type of the remote containers.
|
||||
*/
|
||||
|
|
@ -60,24 +48,10 @@ export interface ContainerReferencePluginOptions {
|
|||
* Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.
|
||||
*/
|
||||
remotes: Remotes;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container.
|
||||
* The name of the share scope shared with all remotes (defaults to 'default').
|
||||
*/
|
||||
[k: string]: OverridesConfig | OverridesItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export interface OverridesConfig {
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
import: OverridesItem;
|
||||
shareScope?: string;
|
||||
}
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.
|
||||
|
|
@ -96,4 +70,8 @@ export interface RemotesConfig {
|
|||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
external: RemotesItem | RemotesItems;
|
||||
/**
|
||||
* The name of the share scope shared with this remote.
|
||||
*/
|
||||
shareScope?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,28 +52,6 @@ export type LibraryType =
|
|||
* If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module.
|
||||
*/
|
||||
export type UmdNamedDefine = boolean;
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overridables =
|
||||
| (OverridablesItem | OverridablesObject)[]
|
||||
| OverridablesObject;
|
||||
/**
|
||||
* Request to a module in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItem = string;
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItems = OverridablesItem[];
|
||||
/**
|
||||
* Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overrides = (OverridesItem | OverridesObject)[] | OverridesObject;
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export type OverridesItem = string;
|
||||
/**
|
||||
* Specifies the default type of externals ('amd*', 'umd*', 'system' and 'jsonp' depend on output.libraryTarget set to the same value).
|
||||
*/
|
||||
|
|
@ -109,13 +87,17 @@ export type RemotesItem = string;
|
|||
*/
|
||||
export type RemotesItems = RemotesItem[];
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host. When provided, property name is used as shared key, otherwise shared key is automatically inferred from request.
|
||||
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
export type Shared = (SharedItem | SharedObject)[] | SharedObject;
|
||||
/**
|
||||
* Module that should be shared with remotes and/or host.
|
||||
* A module that should be shared in the share scope.
|
||||
*/
|
||||
export type SharedItem = string;
|
||||
/**
|
||||
* Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.
|
||||
*/
|
||||
export type SharedVersionArray = (number | string)[];
|
||||
|
||||
export interface ModuleFederationPluginOptions {
|
||||
/**
|
||||
|
|
@ -134,14 +116,6 @@ export interface ModuleFederationPluginOptions {
|
|||
* The name of the container.
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
overridables?: Overridables;
|
||||
/**
|
||||
* Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
overrides?: Overrides;
|
||||
/**
|
||||
* The external type of the remote containers.
|
||||
*/
|
||||
|
|
@ -151,7 +125,11 @@ export interface ModuleFederationPluginOptions {
|
|||
*/
|
||||
remotes?: Remotes;
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host. When provided, property name is used as shared key, otherwise shared key is automatically inferred from request.
|
||||
* Share scope name used for all shared modules (defaults to 'default').
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
shared?: Shared;
|
||||
}
|
||||
|
|
@ -236,42 +214,6 @@ export interface LibraryCustomUmdObject {
|
|||
*/
|
||||
root?: string[] | string;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridablesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
[k: string]: OverridablesConfig | OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export interface OverridablesConfig {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
import: OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
[k: string]: OverridesConfig | OverridesItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
export interface OverridesConfig {
|
||||
/**
|
||||
* Request to a module in this container that should override overridable modules in the remote container.
|
||||
*/
|
||||
import: OverridesItem;
|
||||
}
|
||||
/**
|
||||
* Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.
|
||||
*/
|
||||
|
|
@ -289,22 +231,54 @@ export interface RemotesConfig {
|
|||
* Container locations from which modules should be resolved and loaded at runtime.
|
||||
*/
|
||||
external: RemotesItem | RemotesItems;
|
||||
/**
|
||||
* The name of the share scope shared with this remote.
|
||||
*/
|
||||
shareScope?: string;
|
||||
}
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host. Property names are used as shared keys.
|
||||
* Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.
|
||||
*/
|
||||
export interface SharedObject {
|
||||
/**
|
||||
* Modules that should be shared with remotes and/or host.
|
||||
* Modules that should be shared in the share scope.
|
||||
*/
|
||||
[k: string]: SharedConfig | SharedItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be shared with remotes and/or host.
|
||||
* Advanced configuration for modules that should be shared in the share scope.
|
||||
*/
|
||||
export interface SharedConfig {
|
||||
/**
|
||||
* Module that should be shared with remotes and/or host.
|
||||
* Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.
|
||||
*/
|
||||
import: SharedItem;
|
||||
eager?: boolean;
|
||||
/**
|
||||
* Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.
|
||||
*/
|
||||
import?: false | SharedItem;
|
||||
/**
|
||||
* Version requirement from module in share scope.
|
||||
*/
|
||||
requiredVersion?: string | SharedVersionArray;
|
||||
/**
|
||||
* Module is looked up under this key from the share scope.
|
||||
*/
|
||||
shareKey?: string;
|
||||
/**
|
||||
* Share scope name.
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Allow only a single version of the shared module in share scope (disabled by default).
|
||||
*/
|
||||
singleton?: boolean;
|
||||
/**
|
||||
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
|
||||
*/
|
||||
strictVersion?: boolean;
|
||||
/**
|
||||
* Version of the provided module. Will replace lower matching versions, but not higher.
|
||||
*/
|
||||
version?: false | string | SharedVersionArray;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export type Overridables =
|
||||
| (OverridablesItem | OverridablesObject)[]
|
||||
| OverridablesObject;
|
||||
/**
|
||||
* Request to a module in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItem = string;
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export type OverridablesItems = OverridablesItem[];
|
||||
|
||||
/**
|
||||
* Modules that should be able to be overridden. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
export interface OverridablesPluginOptions {
|
||||
/**
|
||||
* Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.
|
||||
*/
|
||||
overridables?: Overridables;
|
||||
}
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.
|
||||
*/
|
||||
export interface OverridablesObject {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
[k: string]: OverridablesConfig | OverridablesItem | OverridablesItems;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
export interface OverridablesConfig {
|
||||
/**
|
||||
* Requests to modules in this container that should be able to be overridden by the host.
|
||||
*/
|
||||
import: OverridablesItem | OverridablesItems;
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be consumed from share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
export type Consumes = (ConsumesItem | ConsumesObject)[] | ConsumesObject;
|
||||
/**
|
||||
* A module that should be consumed from share scope.
|
||||
*/
|
||||
export type ConsumesItem = string;
|
||||
/**
|
||||
* Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.
|
||||
*/
|
||||
export type SharedVersionArray = (number | string)[];
|
||||
|
||||
/**
|
||||
* Options for consuming shared modules.
|
||||
*/
|
||||
export interface ConsumeSharedPluginOptions {
|
||||
/**
|
||||
* Modules that should be consumed from share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
consumes: Consumes;
|
||||
/**
|
||||
* Share scope name used for all consumed modules (defaults to 'default').
|
||||
*/
|
||||
shareScope?: string;
|
||||
}
|
||||
/**
|
||||
* Modules that should be consumed from share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.
|
||||
*/
|
||||
export interface ConsumesObject {
|
||||
/**
|
||||
* Modules that should be consumed from share scope.
|
||||
*/
|
||||
[k: string]: ConsumesConfig | ConsumesItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be consumed from share scope.
|
||||
*/
|
||||
export interface ConsumesConfig {
|
||||
/**
|
||||
* Include the fallback module directly instead behind an async request. This allows to use fallback module in initial load too. All possible shared modules need to be eager too.
|
||||
*/
|
||||
eager?: boolean;
|
||||
/**
|
||||
* Fallback module if no shared module is found in share scope. Defaults to the property name.
|
||||
*/
|
||||
import?: false | ConsumesItem;
|
||||
/**
|
||||
* Version requirement from module in share scope.
|
||||
*/
|
||||
requiredVersion?: string | SharedVersionArray;
|
||||
/**
|
||||
* Module is looked up under this key from the share scope.
|
||||
*/
|
||||
shareKey?: string;
|
||||
/**
|
||||
* Share scope name.
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Allow only a single version of the shared module in share scope (disabled by default).
|
||||
*/
|
||||
singleton?: boolean;
|
||||
/**
|
||||
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
|
||||
*/
|
||||
strictVersion?: boolean;
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be provided as shared modules to the share scope. When provided, property name is used as share key, otherwise share key is automatically inferred from request.
|
||||
*/
|
||||
export type Provides = (ProvidesItem | ProvidesObject)[] | ProvidesObject;
|
||||
/**
|
||||
* Request to a module that should be provided as shared module to the share scope.
|
||||
*/
|
||||
export type ProvidesItem = string;
|
||||
/**
|
||||
* Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.
|
||||
*/
|
||||
export type SharedVersionArray = (number | string)[];
|
||||
|
||||
export interface ProvideSharedPluginOptions {
|
||||
/**
|
||||
* Modules that should be provided as shared modules to the share scope. When provided, property name is used as share key, otherwise share key is automatically inferred from request.
|
||||
*/
|
||||
provides: Provides;
|
||||
/**
|
||||
* Share scope name used for all provided modules (defaults to 'default').
|
||||
*/
|
||||
shareScope?: string;
|
||||
}
|
||||
/**
|
||||
* Modules that should be provided as shared modules to the share scope. Property names are used as share keys.
|
||||
*/
|
||||
export interface ProvidesObject {
|
||||
/**
|
||||
* Modules that should be provided as shared modules to the share scope.
|
||||
*/
|
||||
[k: string]: ProvidesConfig | ProvidesItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be provided as shared modules to the share scope.
|
||||
*/
|
||||
export interface ProvidesConfig {
|
||||
/**
|
||||
* Include the provided module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.
|
||||
*/
|
||||
eager?: boolean;
|
||||
/**
|
||||
* Request to a module that should be provided as shared module to the share scope.
|
||||
*/
|
||||
import: ProvidesItem;
|
||||
/**
|
||||
* Share scope name.
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Version of the provided module. Will replace lower matching versions, but not higher.
|
||||
*/
|
||||
version?: false | string | SharedVersionArray;
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* This file was automatically generated.
|
||||
* DO NOT MODIFY BY HAND.
|
||||
* Run `yarn special-lint-fix` to update
|
||||
*/
|
||||
|
||||
/**
|
||||
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
export type Shared = (SharedItem | SharedObject)[] | SharedObject;
|
||||
/**
|
||||
* A module that should be shared in the share scope.
|
||||
*/
|
||||
export type SharedItem = string;
|
||||
/**
|
||||
* Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.
|
||||
*/
|
||||
export type SharedVersionArray = (number | string)[];
|
||||
|
||||
/**
|
||||
* Options for shared modules.
|
||||
*/
|
||||
export interface SharePluginOptions {
|
||||
/**
|
||||
* Share scope name used for all shared modules (defaults to 'default').
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.
|
||||
*/
|
||||
shared: Shared;
|
||||
}
|
||||
/**
|
||||
* Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.
|
||||
*/
|
||||
export interface SharedObject {
|
||||
/**
|
||||
* Modules that should be shared in the share scope.
|
||||
*/
|
||||
[k: string]: SharedConfig | SharedItem;
|
||||
}
|
||||
/**
|
||||
* Advanced configuration for modules that should be shared in the share scope.
|
||||
*/
|
||||
export interface SharedConfig {
|
||||
/**
|
||||
* Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.
|
||||
*/
|
||||
eager?: boolean;
|
||||
/**
|
||||
* Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.
|
||||
*/
|
||||
import?: false | SharedItem;
|
||||
/**
|
||||
* Version requirement from module in share scope.
|
||||
*/
|
||||
requiredVersion?: string | SharedVersionArray;
|
||||
/**
|
||||
* Module is looked up under this key from the share scope.
|
||||
*/
|
||||
shareKey?: string;
|
||||
/**
|
||||
* Share scope name.
|
||||
*/
|
||||
shareScope?: string;
|
||||
/**
|
||||
* Allow only a single version of the shared module in share scope (disabled by default).
|
||||
*/
|
||||
singleton?: boolean;
|
||||
/**
|
||||
* Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).
|
||||
*/
|
||||
strictVersion?: boolean;
|
||||
/**
|
||||
* Version of the provided module. Will replace lower matching versions, but not higher.
|
||||
*/
|
||||
version?: false | string | SharedVersionArray;
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
Let's use `await` at top level in a module `db-connection.js`.
|
||||
This makes sense since the connection to the DB need to established before the module is usable.
|
||||
Let's use `await` at the top level in a module `db-connection.js`.
|
||||
This makes sense since the connection to the DB needs to be established before the module is usable.
|
||||
|
||||
# db-connection.js
|
||||
|
||||
|
|
@ -25,15 +25,15 @@ export const close = () => {
|
|||
But `db-connection.js` is no longer a normal module now.
|
||||
It's an **async module** now.
|
||||
Async modules have a different evaluation semantics.
|
||||
While normal modules evaluate in a synchronous way, async modules evaluate in an asynchronous way.
|
||||
While normal modules evaluate synchronously way, async modules evaluate asynchronously.
|
||||
|
||||
Async modules can't imported with a normal `import`.
|
||||
Async modules can't be imported with a normal `import`.
|
||||
They need to be imported with `import await`.
|
||||
|
||||
The main reason for this is to make the using module aware of the different evaluation semantics.
|
||||
|
||||
Using `import await` in a module also makes the module an async module.
|
||||
You can see it as form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
You can see it as a form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
All `import`s and `import await`s hoist and are evaluated in parallel.
|
||||
|
||||
`import await` doesn't affect tree shaking negatively.
|
||||
|
|
@ -56,7 +56,7 @@ Now it looks like that this pattern will continue and will infect all using modu
|
|||
Yes, this is kind of true and makes sense.
|
||||
All these modules have their evaluation semantics changed to be async.
|
||||
|
||||
But you as developer don't want this.
|
||||
But you as a developer don't want this.
|
||||
You want to break the chain at a point in your module graph where it makes sense.
|
||||
Luckily there is a nice way to break the chain.
|
||||
|
||||
|
|
@ -113,12 +113,12 @@ import { CreateUserAction } from "./Actions.js";
|
|||
```
|
||||
|
||||
Note that you may `import await` from a normal module too.
|
||||
This is legal, but mostly unneeded.
|
||||
`import await` may also been seen by developers as hint that this dependency does some async actions and may delay evaluation.
|
||||
This is legal, but mostly not required.
|
||||
`import await` may also be seen by developers as a hint that this dependency does some async actions and may delay evaluation.
|
||||
|
||||
As guideline you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
As a guideline, you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
Doing async actions at application bootstrap will delay your application startup and may be negative for UX.
|
||||
Use `import()` to do async action on demand or in background and use spinners or other indicators to inform the user about background actions.
|
||||
Use `import()` to do async action on-demand or in the background and use spinners or other indicators to inform the user about background actions.
|
||||
|
||||
When compiling for other targets like node.js, electron or WebWorkers, it may be fine that your entry point becomes an async module.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Let's use `await` at top level in a module `db-connection.js`.
|
||||
This makes sense since the connection to the DB need to established before the module is usable.
|
||||
Let's use `await` at the top level in a module `db-connection.js`.
|
||||
This makes sense since the connection to the DB needs to be established before the module is usable.
|
||||
|
||||
# db-connection.js
|
||||
|
||||
|
|
@ -10,15 +10,15 @@ _{{db-connection.js}}_
|
|||
But `db-connection.js` is no longer a normal module now.
|
||||
It's an **async module** now.
|
||||
Async modules have a different evaluation semantics.
|
||||
While normal modules evaluate in a synchronous way, async modules evaluate in an asynchronous way.
|
||||
While normal modules evaluate synchronously, async modules evaluate asynchronously.
|
||||
|
||||
Async modules can't imported with a normal `import`.
|
||||
Async modules can't be imported with a normal `import`.
|
||||
They need to be imported with `import await`.
|
||||
|
||||
The main reason for this is to make the using module aware of the different evaluation semantics.
|
||||
|
||||
Using `import await` in a module also makes the module an async module.
|
||||
You can see it as form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
You can see it as a form of top-level-await, but it's a bit different because imports hoist, so does `import await`.
|
||||
All `import`s and `import await`s hoist and are evaluated in parallel.
|
||||
|
||||
`import await` doesn't affect tree shaking negatively.
|
||||
|
|
@ -35,7 +35,7 @@ Now it looks like that this pattern will continue and will infect all using modu
|
|||
Yes, this is kind of true and makes sense.
|
||||
All these modules have their evaluation semantics changed to be async.
|
||||
|
||||
But you as developer don't want this.
|
||||
But you as a developer don't want this.
|
||||
You want to break the chain at a point in your module graph where it makes sense.
|
||||
Luckily there is a nice way to break the chain.
|
||||
|
||||
|
|
@ -62,12 +62,12 @@ _{{example.js}}_
|
|||
```
|
||||
|
||||
Note that you may `import await` from a normal module too.
|
||||
This is legal, but mostly unneeded.
|
||||
`import await` may also been seen by developers as hint that this dependency does some async actions and may delay evaluation.
|
||||
This is legal, but mostly not required.
|
||||
`import await` may also be seen by developers as a hint that this dependency does some async actions and may delay evaluation.
|
||||
|
||||
As guideline you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
As a guideline, you should prevent your application entry point to become an async module when compiling for web targets.
|
||||
Doing async actions at application bootstrap will delay your application startup and may be negative for UX.
|
||||
Use `import()` to do async action on demand or in background and use spinners or other indicators to inform the user about background actions.
|
||||
Use `import()` to do async action on-demand or in the background and use spinners or other indicators to inform the user about background actions.
|
||||
|
||||
When compiling for other targets like node.js, electron or WebWorkers, it may be fine that your entry point becomes an async module.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
This very simple example shows usage of WebAssembly.
|
||||
This is a simple example that shows the usage of WebAssembly.
|
||||
|
||||
WebAssembly modules can be imported like other async modules with `import await` or `import()`.
|
||||
They are downloaded and instantiated in a streaming way when importing.
|
||||
When importing, they are downloaded and instantiated in a streaming way.
|
||||
|
||||
# example.js
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
This very simple example shows usage of WebAssembly.
|
||||
This is a simple example that shows the usage of WebAssembly.
|
||||
|
||||
WebAssembly modules can be imported like other async modules with `import await` or `import()`.
|
||||
They are downloaded and instantiated in a streaming way when importing.
|
||||
When importing, they are downloaded and instantiated in a streaming way.
|
||||
|
||||
# example.js
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,18 @@ const REPLACEMENTS = {
|
|||
req: [RuntimeGlobals.systemContext],
|
||||
type: "object",
|
||||
assign: false
|
||||
},
|
||||
__webpack_share_scopes__: {
|
||||
expr: RuntimeGlobals.shareScopeMap,
|
||||
req: [RuntimeGlobals.shareScopeMap],
|
||||
type: "object",
|
||||
assign: false
|
||||
},
|
||||
__webpack_init_sharing__: {
|
||||
expr: RuntimeGlobals.initializeSharing,
|
||||
req: [RuntimeGlobals.initializeSharing],
|
||||
type: "function",
|
||||
assign: true
|
||||
}
|
||||
};
|
||||
/* eslint-enable camelcase */
|
||||
|
|
|
|||
|
|
@ -534,6 +534,13 @@ class Chunk {
|
|||
return chunks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Set<Chunk>} a set of all the initial chunks (including itself)
|
||||
*/
|
||||
getAllInitialChunks() {
|
||||
return intersect(Array.from(this.groupsIterable, g => new Set(g.chunks)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Set<Chunk>} a set of all the referenced chunks (including itself)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -150,7 +150,8 @@ const {
|
|||
|
||||
/**
|
||||
* @typedef {Object} EntryData
|
||||
* @property {Dependency[]} dependencies dependencies of the entrypoint
|
||||
* @property {Dependency[]} dependencies dependencies of the entrypoint that should be evaluated at startup
|
||||
* @property {Dependency[]} includeDependencies dependencies of the entrypoint that should be included by not evaluated
|
||||
* @property {EntryOptions} options options of the entrypoint
|
||||
*/
|
||||
|
||||
|
|
@ -701,6 +702,14 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
|
||||
/** @type {Map<string, EntryData>} */
|
||||
this.entries = new Map();
|
||||
/** @type {EntryData} */
|
||||
this.globalEntry = {
|
||||
dependencies: [],
|
||||
includeDependencies: [],
|
||||
options: {
|
||||
name: undefined
|
||||
}
|
||||
};
|
||||
/** @type {Map<string, Entrypoint>} */
|
||||
this.entrypoints = new Map();
|
||||
/** @type {Set<Chunk>} */
|
||||
|
|
@ -1514,9 +1523,8 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} context context path for entry
|
||||
* @param {Dependency} entry entry dependency being created
|
||||
* @param {Dependency} entry entry dependency that should be followed
|
||||
* @param {string | EntryOptions} optionsOrName options or deprecated name of entry
|
||||
* @param {ModuleCallback} callback callback function
|
||||
* @returns {void} returns
|
||||
|
|
@ -1528,19 +1536,51 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
? optionsOrName
|
||||
: { name: optionsOrName };
|
||||
|
||||
this._addEntryItem(context, entry, "dependencies", options, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} context context path for entry
|
||||
* @param {Dependency} dependency dependency that should be followed
|
||||
* @param {EntryOptions} options options
|
||||
* @param {ModuleCallback} callback callback function
|
||||
* @returns {void} returns
|
||||
*/
|
||||
addInclude(context, dependency, options, callback) {
|
||||
this._addEntryItem(
|
||||
context,
|
||||
dependency,
|
||||
"includeDependencies",
|
||||
options,
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} context context path for entry
|
||||
* @param {Dependency} entry entry dependency that should be followed
|
||||
* @param {"dependencies" | "includeDependencies"} target type of entry
|
||||
* @param {EntryOptions} options options
|
||||
* @param {ModuleCallback} callback callback function
|
||||
* @returns {void} returns
|
||||
*/
|
||||
_addEntryItem(context, entry, target, options, callback) {
|
||||
const { name } = options;
|
||||
let entryData = this.entries.get(name);
|
||||
let entryData =
|
||||
name !== undefined ? this.entries.get(name) : this.globalEntry;
|
||||
if (entryData === undefined) {
|
||||
entryData = {
|
||||
dependencies: [entry],
|
||||
dependencies: [],
|
||||
includeDependencies: [],
|
||||
options: {
|
||||
name: undefined,
|
||||
...options
|
||||
}
|
||||
};
|
||||
entryData[target].push(entry);
|
||||
this.entries.set(name, entryData);
|
||||
} else {
|
||||
entryData.dependencies.push(entry);
|
||||
entryData[target].push(entry);
|
||||
for (const key of Object.keys(options)) {
|
||||
if (entryData.options[key] === options[key]) continue;
|
||||
if (entryData.options[key] === undefined) {
|
||||
|
|
@ -1700,7 +1740,9 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
|
||||
this.logger.time("create chunks");
|
||||
this.hooks.beforeChunks.call();
|
||||
for (const [name, { dependencies, options }] of this.entries) {
|
||||
const chunkGraphInit = new Map();
|
||||
for (const [name, { dependencies, includeDependencies, options }] of this
|
||||
.entries) {
|
||||
const chunk = this.addChunk(name);
|
||||
chunk.name = name;
|
||||
if (options.filename) {
|
||||
|
|
@ -1713,13 +1755,35 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
this.chunkGroups.push(entrypoint);
|
||||
connectChunkGroupAndChunk(entrypoint, chunk);
|
||||
|
||||
for (const dep of dependencies) {
|
||||
for (const dep of [...this.globalEntry.dependencies, ...dependencies]) {
|
||||
entrypoint.addOrigin(null, { name }, /** @type {any} */ (dep).request);
|
||||
|
||||
const module = this.moduleGraph.getModule(dep);
|
||||
if (module) {
|
||||
chunkGraph.connectChunkAndEntryModule(chunk, module, entrypoint);
|
||||
this.assignDepth(module);
|
||||
const modulesList = chunkGraphInit.get(entrypoint);
|
||||
if (modulesList === undefined) {
|
||||
chunkGraphInit.set(entrypoint, [module]);
|
||||
} else {
|
||||
modulesList.push(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const dep of [
|
||||
...this.globalEntry.includeDependencies,
|
||||
...includeDependencies
|
||||
]) {
|
||||
const module = this.moduleGraph.getModule(dep);
|
||||
if (module) {
|
||||
this.assignDepth(module);
|
||||
const modulesList = chunkGraphInit.get(entrypoint);
|
||||
if (modulesList === undefined) {
|
||||
chunkGraphInit.set(entrypoint, [module]);
|
||||
} else {
|
||||
modulesList.push(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1742,10 +1806,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
}
|
||||
}
|
||||
}
|
||||
buildChunkGraph(
|
||||
this,
|
||||
/** @type {Entrypoint[]} */ (this.chunkGroups.slice())
|
||||
);
|
||||
buildChunkGraph(this, chunkGraphInit);
|
||||
this.hooks.afterChunks.call(this.chunks);
|
||||
this.logger.timeEnd("create chunks");
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ class EntryPlugin {
|
|||
constructor(context, entry, options) {
|
||||
this.context = context;
|
||||
this.entry = entry;
|
||||
this.options = options;
|
||||
this.options = options || "";
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -835,6 +835,13 @@ class FileSystemInfo {
|
|||
if (optimizationEntry.shared > 0) {
|
||||
// It's a shared snapshot
|
||||
// We can't change it, so we can only use it when all files match
|
||||
// and startTime is compatible
|
||||
if (
|
||||
startTime &&
|
||||
(!snapshot.startTime || snapshot.startTime > startTime)
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const nonSharedFiles = new Set();
|
||||
for (const path of optimizationEntry.snapshotContent) {
|
||||
if (!capturedFiles.has(path)) {
|
||||
|
|
@ -864,7 +871,13 @@ class FileSystemInfo {
|
|||
}
|
||||
// Create and attach snapshot
|
||||
/** @type {Snapshot} */
|
||||
const commonSnapshot = { fileTimestamps: commonMap };
|
||||
const commonSnapshot = {
|
||||
startTime:
|
||||
startTime && snapshot.startTime
|
||||
? Math.min(startTime, snapshot.startTime)
|
||||
: startTime || snapshot.startTime,
|
||||
fileTimestamps: commonMap
|
||||
};
|
||||
children.add(commonSnapshot);
|
||||
if (!snapshot.children) snapshot.children = new Set();
|
||||
snapshot.children.add(commonSnapshot);
|
||||
|
|
@ -889,7 +902,6 @@ class FileSystemInfo {
|
|||
const ts = snapshot.fileTimestamps.get(path);
|
||||
if (ts === undefined) continue;
|
||||
commonMap.set(path, ts);
|
||||
snapshot.fileTimestamps.delete(path);
|
||||
}
|
||||
if (commonMap.size < 2) {
|
||||
// Common part it too small
|
||||
|
|
@ -897,7 +909,13 @@ class FileSystemInfo {
|
|||
}
|
||||
// Create and attach snapshot
|
||||
/** @type {Snapshot} */
|
||||
const commonSnapshot = { fileTimestamps: commonMap };
|
||||
const commonSnapshot = {
|
||||
startTime:
|
||||
startTime && snapshot.startTime
|
||||
? Math.min(startTime, snapshot.startTime)
|
||||
: startTime || snapshot.startTime,
|
||||
fileTimestamps: commonMap
|
||||
};
|
||||
children.add(commonSnapshot);
|
||||
if (!snapshot.children) snapshot.children = new Set();
|
||||
snapshot.children.add(commonSnapshot);
|
||||
|
|
@ -1243,7 +1261,7 @@ class FileSystemInfo {
|
|||
}
|
||||
if (current) {
|
||||
// For existing items only
|
||||
if (current.safeTime > startTime) {
|
||||
if (typeof startTime === "number" && current.safeTime > startTime) {
|
||||
// If a change happened after starting reading the item
|
||||
// this may no longer be valid
|
||||
if (this._remainingLogs > 0) {
|
||||
|
|
|
|||
|
|
@ -147,13 +147,28 @@ class FlagDependencyUsagePlugin {
|
|||
/** @type {Queue<DependenciesBlock>} */
|
||||
const queue = new Queue();
|
||||
|
||||
for (const { dependencies: deps } of compilation.entries.values()) {
|
||||
const processEntryDependency = dep => {
|
||||
const module = moduleGraph.getModule(dep);
|
||||
if (module) {
|
||||
processModule(module, NO_EXPORTS_REFERENCED);
|
||||
queue.enqueue(module);
|
||||
}
|
||||
};
|
||||
for (const dep of compilation.globalEntry.dependencies) {
|
||||
processEntryDependency(dep);
|
||||
}
|
||||
for (const dep of compilation.globalEntry.includeDependencies) {
|
||||
processEntryDependency(dep);
|
||||
}
|
||||
for (const {
|
||||
dependencies: deps,
|
||||
includeDependencies: includeDeps
|
||||
} of compilation.entries.values()) {
|
||||
for (const dep of deps) {
|
||||
const module = moduleGraph.getModule(dep);
|
||||
if (module) {
|
||||
processModule(module, NO_EXPORTS_REFERENCED);
|
||||
queue.enqueue(module);
|
||||
}
|
||||
processEntryDependency(dep);
|
||||
}
|
||||
for (const dep of includeDeps) {
|
||||
processEntryDependency(dep);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ const makeSerializable = require("./util/makeSerializable");
|
|||
/**
|
||||
* @typedef {Object} CodeGenerationResult
|
||||
* @property {Map<string, Source>} sources the resulting sources for all source types
|
||||
* @property {Map<string, any>=} data the resulting data for all source types
|
||||
* @property {ReadonlySet<string>} runtimeRequirements the runtime requirements
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -196,9 +196,16 @@ exports.interceptModuleExecution = "__webpack_require__.i";
|
|||
exports.global = "__webpack_require__.g";
|
||||
|
||||
/**
|
||||
* the overrides mapping
|
||||
* an object with all share scopes
|
||||
*/
|
||||
exports.overrides = "__webpack_require__.O";
|
||||
exports.shareScopeMap = "__webpack_require__.S";
|
||||
|
||||
/**
|
||||
* The sharing init sequence function (only runs once per share scope).
|
||||
* Has one argument, the name of the share scope.
|
||||
* Creates a share scope if not existing
|
||||
*/
|
||||
exports.initializeSharing = "__webpack_require__.I";
|
||||
|
||||
/**
|
||||
* the filename of the HMR manifest
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ const HasOwnPropertyRuntimeModule = require("./runtime/HasOwnPropertyRuntimeModu
|
|||
const MakeNamespaceObjectRuntimeModule = require("./runtime/MakeNamespaceObjectRuntimeModule");
|
||||
const PublicPathRuntimeModule = require("./runtime/PublicPathRuntimeModule");
|
||||
const SystemContextRuntimeModule = require("./runtime/SystemContextRuntimeModule");
|
||||
const ShareRuntimeModule = require("./sharing/ShareRuntimeModule");
|
||||
|
||||
/** @typedef {import("./Chunk")} Chunk */
|
||||
/** @typedef {import("./Compiler")} Compiler */
|
||||
|
|
@ -43,7 +44,9 @@ const GLOBALS_ON_REQUIRE = [
|
|||
RuntimeGlobals.scriptNonce,
|
||||
RuntimeGlobals.uncaughtErrorHandler,
|
||||
RuntimeGlobals.wasmInstances,
|
||||
RuntimeGlobals.instantiateWasm
|
||||
RuntimeGlobals.instantiateWasm,
|
||||
RuntimeGlobals.shareScopeMap,
|
||||
RuntimeGlobals.initializeSharing
|
||||
];
|
||||
|
||||
const MODULE_DEPENDENCIES = {
|
||||
|
|
@ -60,7 +63,9 @@ const TREE_DEPENDENCIES = {
|
|||
RuntimeGlobals.definePropertyGetters,
|
||||
RuntimeGlobals.makeNamespaceObject,
|
||||
RuntimeGlobals.require
|
||||
]
|
||||
],
|
||||
[RuntimeGlobals.initializeSharing]: [RuntimeGlobals.shareScopeMap],
|
||||
[RuntimeGlobals.shareScopeMap]: [RuntimeGlobals.hasOwnProperty]
|
||||
};
|
||||
|
||||
class RuntimePlugin {
|
||||
|
|
@ -254,6 +259,12 @@ class RuntimePlugin {
|
|||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
set.add(RuntimeGlobals.ensureChunkHandlers);
|
||||
});
|
||||
compilation.hooks.runtimeRequirementInTree
|
||||
.for(RuntimeGlobals.shareScopeMap)
|
||||
.tap("RuntimePlugin", (chunk, set) => {
|
||||
compilation.addRuntimeModule(chunk, new ShareRuntimeModule());
|
||||
return true;
|
||||
});
|
||||
// TODO webpack 6: remove CompatRuntimePlugin
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
"RuntimePlugin",
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const propertyAccess = require("./util/propertyAccess");
|
|||
/** @typedef {import("../declarations/WebpackOptions").OutputNormalized} OutputOptions */
|
||||
/** @typedef {import("./AsyncDependenciesBlock")} AsyncDependenciesBlock */
|
||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("./Dependency")} Dependency */
|
||||
/** @typedef {import("./InitFragment")} InitFragment */
|
||||
/** @typedef {import("./Module")} Module */
|
||||
/** @typedef {import("./ModuleGraph")} ModuleGraph */
|
||||
|
|
@ -725,6 +726,59 @@ class RuntimeTemplate {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} options options
|
||||
* @param {AsyncDependenciesBlock} options.block the async block
|
||||
* @param {ChunkGraph} options.chunkGraph the chunk graph
|
||||
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
|
||||
* @param {string=} options.request request string used originally
|
||||
* @returns {string} expression
|
||||
*/
|
||||
asyncModuleFactory({ block, chunkGraph, runtimeRequirements, request }) {
|
||||
const dep = block.dependencies[0];
|
||||
const module = chunkGraph.moduleGraph.getModule(dep);
|
||||
const ensureChunk = this.blockPromise({
|
||||
block,
|
||||
message: "",
|
||||
chunkGraph,
|
||||
runtimeRequirements
|
||||
});
|
||||
const factory = this.returningFunction(
|
||||
this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
runtimeRequirements
|
||||
})
|
||||
);
|
||||
return this.returningFunction(
|
||||
ensureChunk.startsWith("Promise.resolve(")
|
||||
? `${factory}`
|
||||
: `${ensureChunk}.then(${this.returningFunction(factory)})`
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} options options
|
||||
* @param {Dependency} options.dependency the dependency
|
||||
* @param {ChunkGraph} options.chunkGraph the chunk graph
|
||||
* @param {Set<string>} options.runtimeRequirements if set, will be filled with runtime requirements
|
||||
* @param {string=} options.request request string used originally
|
||||
* @returns {string} expression
|
||||
*/
|
||||
syncModuleFactory({ dependency, chunkGraph, runtimeRequirements, request }) {
|
||||
const module = chunkGraph.moduleGraph.getModule(dependency);
|
||||
const factory = this.returningFunction(
|
||||
this.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request,
|
||||
runtimeRequirements
|
||||
})
|
||||
);
|
||||
return this.returningFunction(factory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} options options
|
||||
* @param {string} options.exportsArgument the name of the exports object
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ const extractBlockModulesMap = compilation => {
|
|||
*
|
||||
* @param {Logger} logger a logger
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @param {Entrypoint[]} inputEntrypoints input groups
|
||||
* @param {Map<Entrypoint, Module[]>} inputEntrypointsAndModules chunk groups which are processed with the modules
|
||||
* @param {Map<ChunkGroup, ChunkGroupInfo>} chunkGroupInfoMap mapping from chunk group to available modules
|
||||
* @param {Map<ChunkGroup, ChunkGroupDep[]>} chunkGroupDependencies dependencies for chunk groups
|
||||
* @param {Set<DependenciesBlock>} blocksWithNestedBlocks flag for blocks that have nested blocks
|
||||
|
|
@ -143,7 +143,7 @@ const extractBlockModulesMap = compilation => {
|
|||
const visitModules = (
|
||||
logger,
|
||||
compilation,
|
||||
inputEntrypoints,
|
||||
inputEntrypointsAndModules,
|
||||
chunkGroupInfoMap,
|
||||
chunkGroupDependencies,
|
||||
blocksWithNestedBlocks,
|
||||
|
|
@ -179,7 +179,7 @@ const visitModules = (
|
|||
|
||||
// Fill queue with entrypoint modules
|
||||
// Create ChunkGroupInfo for entrypoints
|
||||
for (const chunkGroup of inputEntrypoints) {
|
||||
for (const [chunkGroup, modules] of inputEntrypointsAndModules) {
|
||||
/** @type {ChunkGroupInfo} */
|
||||
const chunkGroupInfo = {
|
||||
chunkGroup,
|
||||
|
|
@ -200,27 +200,24 @@ const visitModules = (
|
|||
// This means no module is added until other sets are merged into
|
||||
// this minAvailableModules (by the parent entrypoints)
|
||||
const skippedItems = new Set();
|
||||
for (const chunk of chunkGroup.chunks) {
|
||||
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
|
||||
skippedItems.add(module);
|
||||
}
|
||||
for (const module of modules) {
|
||||
skippedItems.add(module);
|
||||
}
|
||||
chunkGroupInfo.skippedItems = skippedItems;
|
||||
chunkGroupsForCombining.add(chunkGroupInfo);
|
||||
} else {
|
||||
// The application may start here: We start with an empty list of available modules
|
||||
chunkGroupInfo.minAvailableModules = EMPTY_SET;
|
||||
for (const chunk of chunkGroup.chunks) {
|
||||
for (const module of chunkGraph.getChunkEntryModulesIterable(chunk)) {
|
||||
queue.push({
|
||||
action: ADD_AND_ENTER_MODULE,
|
||||
block: module,
|
||||
module,
|
||||
chunk,
|
||||
chunkGroup,
|
||||
chunkGroupInfo
|
||||
});
|
||||
}
|
||||
const chunk = chunkGroup.chunks[0];
|
||||
for (const module of modules) {
|
||||
queue.push({
|
||||
action: ADD_AND_ENTER_MODULE,
|
||||
block: module,
|
||||
module,
|
||||
chunk,
|
||||
chunkGroup,
|
||||
chunkGroupInfo
|
||||
});
|
||||
}
|
||||
}
|
||||
chunkGroupInfoMap.set(chunkGroup, chunkGroupInfo);
|
||||
|
|
@ -902,10 +899,10 @@ const cleanupUnconnectedGroups = (compilation, allCreatedChunkGroups) => {
|
|||
/**
|
||||
* This method creates the Chunk graph from the Module graph
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @param {Entrypoint[]} inputEntrypoints chunk groups which are processed
|
||||
* @param {Map<Entrypoint, Module[]>} inputEntrypointsAndModules chunk groups which are processed with the modules
|
||||
* @returns {void}
|
||||
*/
|
||||
const buildChunkGraph = (compilation, inputEntrypoints) => {
|
||||
const buildChunkGraph = (compilation, inputEntrypointsAndModules) => {
|
||||
const logger = compilation.getLogger("webpack.buildChunkGraph");
|
||||
|
||||
// SHARED STATE
|
||||
|
|
@ -928,7 +925,7 @@ const buildChunkGraph = (compilation, inputEntrypoints) => {
|
|||
visitModules(
|
||||
logger,
|
||||
compilation,
|
||||
inputEntrypoints,
|
||||
inputEntrypointsAndModules,
|
||||
chunkGroupInfoMap,
|
||||
chunkGroupDependencies,
|
||||
blocksWithNestedBlocks,
|
||||
|
|
|
|||
|
|
@ -14,11 +14,13 @@ class ContainerEntryDependency extends Dependency {
|
|||
/**
|
||||
* @param {string} name entry name
|
||||
* @param {[string, ExposeOptions][]} exposes list of exposed modules
|
||||
* @param {string} shareScope name of the share scope
|
||||
*/
|
||||
constructor(name, exposes) {
|
||||
constructor(name, exposes, shareScope) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.exposes = exposes;
|
||||
this.shareScope = shareScope;
|
||||
this.optional = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,11 +39,13 @@ class ContainerEntryModule extends Module {
|
|||
/**
|
||||
* @param {string} name container entry name
|
||||
* @param {[string, ExposeOptions][]} exposes list of exposed modules
|
||||
* @param {string} shareScope name of the share scope
|
||||
*/
|
||||
constructor(name, exposes) {
|
||||
constructor(name, exposes, shareScope) {
|
||||
super("javascript/dynamic", null);
|
||||
this._name = name;
|
||||
this._exposes = exposes;
|
||||
this._shareScope = shareScope;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -57,7 +59,9 @@ class ContainerEntryModule extends Module {
|
|||
* @returns {string} a unique identifier of the module
|
||||
*/
|
||||
identifier() {
|
||||
return `container entry ${JSON.stringify(this._exposes)}`;
|
||||
return `container entry (${this._shareScope}) ${JSON.stringify(
|
||||
this._exposes
|
||||
)}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -203,16 +207,21 @@ class ContainerEntryModule extends Module {
|
|||
]),
|
||||
");"
|
||||
])};`,
|
||||
`var override = ${runtimeTemplate.basicFunction(
|
||||
"override",
|
||||
`Object.assign(${RuntimeGlobals.overrides}, override);`
|
||||
)};`,
|
||||
`var init = ${runtimeTemplate.basicFunction("shareScope", [
|
||||
`var oldScope = ${RuntimeGlobals.shareScopeMap}[${JSON.stringify(
|
||||
this._shareScope
|
||||
)}];`,
|
||||
`var name = ${JSON.stringify(this._shareScope)}`,
|
||||
`if(oldScope && oldScope !== shareScope) throw new Error("Container initialization failed as it has already been initialized with a different share scope");`,
|
||||
`${RuntimeGlobals.shareScopeMap}[name] = shareScope;`,
|
||||
`return ${RuntimeGlobals.initializeSharing}(name);`
|
||||
])};`,
|
||||
"",
|
||||
"// This exports getters to disallow modifications",
|
||||
`${RuntimeGlobals.definePropertyGetters}(exports, {`,
|
||||
Template.indent([
|
||||
`get: ${runtimeTemplate.returningFunction("get")},`,
|
||||
`override: ${runtimeTemplate.returningFunction("override")}`
|
||||
`init: ${runtimeTemplate.returningFunction("init")}`
|
||||
]),
|
||||
"});"
|
||||
]);
|
||||
|
|
@ -238,14 +247,17 @@ class ContainerEntryModule extends Module {
|
|||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this._name);
|
||||
write(this._exposes);
|
||||
write(this._shareScope);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
static deserialize(context) {
|
||||
const { read } = context;
|
||||
this._exposes = read();
|
||||
super.deserialize(context);
|
||||
const obj = new ContainerEntryModule(read(), read(), read());
|
||||
obj.deserialize(context);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ module.exports = class ContainerEntryModuleFactory extends ModuleFactory {
|
|||
create({ dependencies: [dependency] }, callback) {
|
||||
const dep = /** @type {ContainerEntryDependency} */ (dependency);
|
||||
callback(null, {
|
||||
module: new ContainerEntryModule(dep.name, dep.exposes)
|
||||
module: new ContainerEntryModule(dep.name, dep.exposes, dep.shareScope)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ const schema = require("../../schemas/plugins/container/ContainerPlugin.json");
|
|||
const ContainerEntryDependency = require("./ContainerEntryDependency");
|
||||
const ContainerEntryModuleFactory = require("./ContainerEntryModuleFactory");
|
||||
const ContainerExposedDependency = require("./ContainerExposedDependency");
|
||||
const OverridablesPlugin = require("./OverridablesPlugin");
|
||||
const { parseOptions } = require("./options");
|
||||
|
||||
/** @typedef {import("../../declarations/plugins/container/ContainerPlugin").ContainerPluginOptions} ContainerPluginOptions */
|
||||
|
|
@ -26,8 +25,8 @@ class ContainerPlugin {
|
|||
validateOptions(schema, options, { name: "Container Plugin" });
|
||||
|
||||
this._options = {
|
||||
overridables: options.overridables,
|
||||
name: options.name,
|
||||
shareScope: options.shareScope || "default",
|
||||
library: options.library || {
|
||||
type: "var",
|
||||
name: options.name
|
||||
|
|
@ -51,14 +50,12 @@ class ContainerPlugin {
|
|||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const { name, exposes, filename, library, overridables } = this._options;
|
||||
const { name, exposes, shareScope, filename, library } = this._options;
|
||||
|
||||
compiler.options.output.enabledLibraryTypes.push(library.type);
|
||||
|
||||
new OverridablesPlugin({ overridables }).apply(compiler);
|
||||
|
||||
compiler.hooks.make.tapAsync(PLUGIN_NAME, (compilation, callback) => {
|
||||
const dep = new ContainerEntryDependency(name, exposes);
|
||||
const dep = new ContainerEntryDependency(name, exposes, shareScope);
|
||||
dep.loc = { name };
|
||||
compilation.addEntry(
|
||||
compilation.options.context,
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@ const validateOptions = require("schema-utils");
|
|||
const schema = require("../../schemas/plugins/container/ContainerReferencePlugin.json");
|
||||
const ExternalsPlugin = require("../ExternalsPlugin");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const FallbackDependency = require("./FallbackDependency");
|
||||
const FallbackItemDependency = require("./FallbackItemDependency");
|
||||
const FallbackModuleFactory = require("./FallbackModuleFactory");
|
||||
const RemoteModule = require("./RemoteModule");
|
||||
const RemoteOverrideDependency = require("./RemoteOverrideDependency");
|
||||
const RemoteOverridesDependency = require("./RemoteOverridesDependency");
|
||||
const RemoteOverridesModuleFactory = require("./RemoteOverridesModuleFactory");
|
||||
const RemoteRuntimeModule = require("./RemoteRuntimeModule");
|
||||
const RemoteToExternalDependency = require("./RemoteToExternalDependency");
|
||||
const { parseOptions } = require("./options");
|
||||
|
|
@ -20,7 +20,6 @@ const { parseOptions } = require("./options");
|
|||
/** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").ContainerReferencePluginOptions} ContainerReferencePluginOptions */
|
||||
/** @typedef {import("../../declarations/plugins/container/ContainerReferencePlugin").RemotesConfig} RemotesConfig */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("./RemoteOverridesModule").OverrideOptions} OverrideOptions */
|
||||
|
||||
const slashCode = "/".charCodeAt(0);
|
||||
|
||||
|
|
@ -35,31 +34,16 @@ class ContainerReferencePlugin {
|
|||
this._remotes = parseOptions(
|
||||
options.remotes,
|
||||
item => ({
|
||||
external: Array.isArray(item) ? item : [item]
|
||||
external: Array.isArray(item) ? item : [item],
|
||||
shareScope: options.shareScope || "default"
|
||||
}),
|
||||
item => ({
|
||||
external: Array.isArray(item.external) ? item.external : [item.external]
|
||||
external: Array.isArray(item.external)
|
||||
? item.external
|
||||
: [item.external],
|
||||
shareScope: item.shareScope || options.shareScope || "default"
|
||||
})
|
||||
);
|
||||
/** @type {[string, OverrideOptions][]} */
|
||||
this._overrides = parseOptions(
|
||||
options.overrides,
|
||||
item => {
|
||||
if (Array.isArray(item))
|
||||
throw new Error("Unexpected array of overrides");
|
||||
return {
|
||||
import: item
|
||||
};
|
||||
},
|
||||
item => ({
|
||||
import: item.import
|
||||
})
|
||||
);
|
||||
this._overrides.sort(([a], [b]) => {
|
||||
if (a < b) return -1;
|
||||
if (b < a) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -94,13 +78,13 @@ class ContainerReferencePlugin {
|
|||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
RemoteOverrideDependency,
|
||||
FallbackItemDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
RemoteOverridesDependency,
|
||||
new RemoteOverridesModuleFactory()
|
||||
FallbackDependency,
|
||||
new FallbackModuleFactory()
|
||||
);
|
||||
|
||||
normalModuleFactory.hooks.factorize.tap(
|
||||
|
|
@ -115,7 +99,6 @@ class ContainerReferencePlugin {
|
|||
) {
|
||||
return new RemoteModule(
|
||||
data.request,
|
||||
this._overrides,
|
||||
config.external.map((external, i) =>
|
||||
external.startsWith("internal ")
|
||||
? external.slice(9)
|
||||
|
|
@ -123,7 +106,8 @@ class ContainerReferencePlugin {
|
|||
i ? `/fallback-${i}` : ""
|
||||
}`
|
||||
),
|
||||
`.${data.request.slice(key.length)}`
|
||||
`.${data.request.slice(key.length)}`,
|
||||
config.shareScope
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -135,8 +119,10 @@ class ContainerReferencePlugin {
|
|||
.for(RuntimeGlobals.ensureChunkHandlers)
|
||||
.tap("ContainerReferencePlugin", (chunk, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.moduleFactories);
|
||||
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
set.add(RuntimeGlobals.initializeSharing);
|
||||
set.add(RuntimeGlobals.shareScopeMap);
|
||||
compilation.addRuntimeModule(chunk, new RemoteRuntimeModule());
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Dependency = require("../Dependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
class FallbackDependency extends Dependency {
|
||||
constructor(requests) {
|
||||
super();
|
||||
this.requests = requests;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `fallback ${this.requests.join(" ")}`;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "fallbacks";
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.requests);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
static deserialize(context) {
|
||||
const { read } = context;
|
||||
const obj = new FallbackDependency(read());
|
||||
obj.deserialize(context);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
FallbackDependency,
|
||||
"webpack/lib/container/FallbackDependency"
|
||||
);
|
||||
|
||||
module.exports = FallbackDependency;
|
||||
|
|
@ -8,19 +8,19 @@
|
|||
const ModuleDependency = require("../dependencies/ModuleDependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
class OverridableOriginalDependency extends ModuleDependency {
|
||||
class FallbackItemDependency extends ModuleDependency {
|
||||
constructor(request) {
|
||||
super(request);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "overridable original";
|
||||
return "fallback item";
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
OverridableOriginalDependency,
|
||||
"webpack/lib/container/OverridableOriginalDependency"
|
||||
FallbackItemDependency,
|
||||
"webpack/lib/container/FallbackItemDependency"
|
||||
);
|
||||
|
||||
module.exports = OverridableOriginalDependency;
|
||||
module.exports = FallbackItemDependency;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
|
@ -10,10 +10,10 @@ const Module = require("../Module");
|
|||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const Template = require("../Template");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const OverridableDependenciesBlock = require("./OverridableDependenciesBlock");
|
||||
const OverridableOriginalDependency = require("./OverridableOriginalDependency");
|
||||
const FallbackItemDependency = require("./FallbackItemDependency");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("../ChunkGroup")} ChunkGroup */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
|
|
@ -27,31 +27,24 @@ const OverridableOriginalDependency = require("./OverridableOriginalDependency")
|
|||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
/**
|
||||
* @typedef {Object} OverridableOptions
|
||||
* @property {string} name global overridable name
|
||||
*/
|
||||
const TYPES = new Set(["javascript"]);
|
||||
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
|
||||
|
||||
const TYPES = new Set(["overridable"]);
|
||||
|
||||
class OverridableModule extends Module {
|
||||
class FallbackModule extends Module {
|
||||
/**
|
||||
* @param {string} context context
|
||||
* @param {string} originalRequest original request
|
||||
* @param {OverridableOptions} options overridable options
|
||||
* @param {string[]} requests list of requests to choose one
|
||||
*/
|
||||
constructor(context, originalRequest, options) {
|
||||
super("overridable-module", context);
|
||||
this.originalRequest = originalRequest;
|
||||
this.options = options;
|
||||
constructor(requests) {
|
||||
super("fallback-module");
|
||||
this.requests = requests;
|
||||
this._identifier = `fallback ${this.requests.join(" ")}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} a unique identifier of the module
|
||||
*/
|
||||
identifier() {
|
||||
const { name } = this.options;
|
||||
return `overridable|${name}|${this.context}|${this.originalRequest}`;
|
||||
return this._identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,8 +52,7 @@ class OverridableModule extends Module {
|
|||
* @returns {string} a user readable identifier of the module
|
||||
*/
|
||||
readableIdentifier(requestShortener) {
|
||||
const { name } = this.options;
|
||||
return `overridable ${name} -> ${this.originalRequest}`;
|
||||
return this._identifier;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -68,8 +60,18 @@ class OverridableModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
const { name } = this.options;
|
||||
return `webpack/container/overridable/${name}=${this.originalRequest}`;
|
||||
return `webpack/container/fallback/${this.requests[0]}/and ${
|
||||
this.requests.length - 1
|
||||
} more`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Chunk} chunk the chunk which condition should be checked
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @returns {boolean} true, if the chunk is ok for the module
|
||||
*/
|
||||
chunkCondition(chunk, { chunkGraph }) {
|
||||
return chunkGraph.getNumberOfEntryModules(chunk) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,14 +93,25 @@ class OverridableModule extends Module {
|
|||
*/
|
||||
build(options, compilation, resolver, fs, callback) {
|
||||
this.buildMeta = {};
|
||||
this.buildInfo = {};
|
||||
const block = new OverridableDependenciesBlock();
|
||||
const dep = new OverridableOriginalDependency(this.originalRequest);
|
||||
block.addDependency(dep);
|
||||
this.addBlock(block);
|
||||
this.buildInfo = {
|
||||
strict: true
|
||||
};
|
||||
|
||||
this.clearDependenciesAndBlocks();
|
||||
for (const request of this.requests)
|
||||
this.addDependency(new FallbackItemDependency(request));
|
||||
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string=} type the source type for which the size should be estimated
|
||||
* @returns {number} the estimated size of the module (must be non-zero)
|
||||
*/
|
||||
size(type) {
|
||||
return this.requests.length * 5 + 42;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Set<string>} types available (do not mutate)
|
||||
*/
|
||||
|
|
@ -106,82 +119,55 @@ class OverridableModule extends Module {
|
|||
return TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string=} type the source type for which the size should be estimated
|
||||
* @returns {number} the estimated size of the module (must be non-zero)
|
||||
*/
|
||||
size(type) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Hash} hash the hash used to track dependencies
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {void}
|
||||
*/
|
||||
updateHash(hash, chunkGraph) {
|
||||
hash.update(JSON.stringify(this.options));
|
||||
hash.update(this.originalRequest);
|
||||
super.updateHash(hash, chunkGraph);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CodeGenerationContext} context context for code generation
|
||||
* @returns {CodeGenerationResult} result
|
||||
*/
|
||||
codeGeneration({ chunkGraph, moduleGraph, runtimeTemplate }) {
|
||||
const runtimeRequirements = new Set([RuntimeGlobals.overrides]);
|
||||
const originalBlock = this.blocks[0];
|
||||
const originalDep = originalBlock.dependencies[0];
|
||||
const originalRequest = moduleGraph.getModule(originalDep);
|
||||
const ensureChunk = runtimeTemplate.blockPromise({
|
||||
block: originalBlock,
|
||||
message: "",
|
||||
chunkGraph,
|
||||
runtimeRequirements
|
||||
});
|
||||
const factory = runtimeTemplate.returningFunction(
|
||||
runtimeTemplate.moduleRaw({
|
||||
module: originalRequest,
|
||||
chunkGraph,
|
||||
request: "",
|
||||
runtimeRequirements
|
||||
})
|
||||
codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
|
||||
const ids = this.dependencies.map(dep =>
|
||||
chunkGraph.getModuleId(moduleGraph.getModule(dep))
|
||||
);
|
||||
const code = Template.asString([
|
||||
`var ids = ${JSON.stringify(ids)};`,
|
||||
"var error, result, i = 0;",
|
||||
`var loop = ${runtimeTemplate.basicFunction("next", [
|
||||
"while(i < ids.length) {",
|
||||
Template.indent([
|
||||
"try { next = __webpack_require__(ids[i++]); } catch(e) { return handleError(e); }",
|
||||
"if(next) return next.then ? next.then(handleResult, handleError) : handleResult(next);"
|
||||
]),
|
||||
"}",
|
||||
"if(error) throw error;"
|
||||
])}`,
|
||||
`var handleResult = ${runtimeTemplate.basicFunction("result", [
|
||||
"if(result) return result;",
|
||||
"return loop();"
|
||||
])};`,
|
||||
`var handleError = ${runtimeTemplate.basicFunction("e", [
|
||||
"error = e;",
|
||||
"return loop();"
|
||||
])};`,
|
||||
"module.exports = loop();"
|
||||
]);
|
||||
const sources = new Map();
|
||||
sources.set(
|
||||
"overridable",
|
||||
new RawSource(
|
||||
Template.asString([
|
||||
ensureChunk.startsWith("Promise.resolve(")
|
||||
? `return ${factory};`
|
||||
: `return ${ensureChunk}.then(${runtimeTemplate.returningFunction(
|
||||
factory
|
||||
)});`
|
||||
])
|
||||
)
|
||||
);
|
||||
return {
|
||||
runtimeRequirements,
|
||||
sources
|
||||
};
|
||||
sources.set("javascript", new RawSource(code));
|
||||
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS };
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.originalRequest);
|
||||
write(this.options);
|
||||
write(this.requests);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
static deserialize(context) {
|
||||
const { read } = context;
|
||||
this.originalRequest = read();
|
||||
this.options = read();
|
||||
super.deserialize(context);
|
||||
const obj = new FallbackModule(read());
|
||||
obj.deserialize(context);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(OverridableModule, "webpack/lib/container/OverridableModule");
|
||||
makeSerializable(FallbackModule, "webpack/lib/container/FallbackModule");
|
||||
|
||||
module.exports = OverridableModule;
|
||||
module.exports = FallbackModule;
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra, Zackary Jackson @ScriptedAlchemy, Marais Rossouw @maraisr
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ModuleFactory = require("../ModuleFactory");
|
||||
const FallbackModule = require("./FallbackModule");
|
||||
|
||||
/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
|
||||
/** @typedef {import("../ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
|
||||
/** @typedef {import("./FallbackDependency")} FallbackDependency */
|
||||
|
||||
module.exports = class FallbackModuleFactory extends ModuleFactory {
|
||||
/**
|
||||
* @param {ModuleFactoryCreateData} data data object
|
||||
* @param {function(Error=, ModuleFactoryResult=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
create({ dependencies: [dependency] }, callback) {
|
||||
const dep = /** @type {FallbackDependency} */ (dependency);
|
||||
callback(null, {
|
||||
module: new FallbackModule(dep.requests)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../../schemas/plugins/container/ModuleFederationPlugin.json");
|
||||
const SharePlugin = require("../sharing/SharePlugin");
|
||||
const ContainerPlugin = require("./ContainerPlugin");
|
||||
const ContainerReferencePlugin = require("./ContainerReferencePlugin");
|
||||
|
||||
|
|
@ -14,31 +15,6 @@ const ContainerReferencePlugin = require("./ContainerReferencePlugin");
|
|||
/** @typedef {import("../../declarations/plugins/container/ModuleFederationPlugin").Shared} Shared */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @template O
|
||||
* @param {T[] | O} a first
|
||||
* @param {T[] | O} b second
|
||||
* @returns {(T | O)[] | O} merged
|
||||
*/
|
||||
const merge = (a, b) => {
|
||||
if (!b) return a;
|
||||
if (!a) return b;
|
||||
if (Array.isArray(a)) {
|
||||
if (Array.isArray(b)) {
|
||||
return [...a, ...b];
|
||||
} else {
|
||||
return [...a, b];
|
||||
}
|
||||
} else {
|
||||
if (Array.isArray(b)) {
|
||||
return [a, ...b];
|
||||
} else {
|
||||
return [a, b];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ModuleFederationPlugin {
|
||||
/**
|
||||
* @param {ModuleFederationPluginOptions} options options
|
||||
|
|
@ -75,8 +51,7 @@ class ModuleFederationPlugin {
|
|||
name: options.name,
|
||||
library: options.library || compiler.options.output.library,
|
||||
filename: options.filename,
|
||||
exposes: options.exposes,
|
||||
overridables: merge(options.shared, options.overridables)
|
||||
exposes: options.exposes
|
||||
}).apply(compiler);
|
||||
}
|
||||
if (
|
||||
|
|
@ -90,8 +65,13 @@ class ModuleFederationPlugin {
|
|||
options.remoteType ||
|
||||
(options.library && options.library.type) ||
|
||||
compiler.options.externalsType,
|
||||
remotes: options.remotes,
|
||||
overrides: merge(options.shared, options.overrides)
|
||||
remotes: options.remotes
|
||||
}).apply(compiler);
|
||||
}
|
||||
if (options.shared) {
|
||||
new SharePlugin({
|
||||
shared: options.shared,
|
||||
shareScope: options.shareScope
|
||||
}).apply(compiler);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
||||
|
||||
/** @typedef {import("../ChunkGroup")} ChunkGroup */
|
||||
|
||||
class OverridableDependenciesBlock extends AsyncDependenciesBlock {
|
||||
constructor() {
|
||||
super({});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {ChunkGroup} parentChunkGroup the parent chunk group
|
||||
* @returns {boolean} true when this dependencies block should be loaded async
|
||||
*/
|
||||
isAsync(parentChunkGroup) {
|
||||
return !parentChunkGroup.isInitial();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OverridableDependenciesBlock;
|
||||
|
|
@ -1,194 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../../schemas/plugins/container/OverridablesPlugin.json");
|
||||
const ModuleNotFoundError = require("../ModuleNotFoundError");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const {
|
||||
toConstantDependency,
|
||||
evaluateToString
|
||||
} = require("../javascript/JavascriptParserHelpers");
|
||||
const LazySet = require("../util/LazySet");
|
||||
const OverridableModule = require("./OverridableModule");
|
||||
const OverridableOriginalDependency = require("./OverridableOriginalDependency");
|
||||
const OverridablesRuntimeModule = require("./OverridablesRuntimeModule");
|
||||
const { parseOptions } = require("./options");
|
||||
|
||||
/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
|
||||
/** @typedef {import("../../declarations/plugins/container/OverridablesPlugin").OverridablesConfig} OverridablesConfig */
|
||||
/** @typedef {import("../../declarations/plugins/container/OverridablesPlugin").OverridablesPluginOptions} OverridablesPluginOptions */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("./OverridableModule").OverridableOptions} OverridableOptions */
|
||||
|
||||
const PLUGIN_NAME = "OverridablesPlugin";
|
||||
|
||||
class OverridablesPlugin {
|
||||
/**
|
||||
* @param {OverridablesPluginOptions} options options
|
||||
*/
|
||||
constructor(options) {
|
||||
if (typeof options !== "string") {
|
||||
validateOptions(schema, options, { name: "Overridables Plugin" });
|
||||
}
|
||||
|
||||
this._overridables = parseOptions(
|
||||
options.overridables,
|
||||
item => ({
|
||||
import: Array.isArray(item) ? item : [item]
|
||||
}),
|
||||
item => ({
|
||||
import: Array.isArray(item.import) ? item.import : [item.import]
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.thisCompilation.tap(
|
||||
PLUGIN_NAME,
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
compilation.dependencyFactories.set(
|
||||
OverridableOriginalDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
/** @type {Map<string, OverridableOptions>} */
|
||||
const resolvedOverridables = new Map();
|
||||
const resolveContext = {
|
||||
/** @type {LazySet<string>} */
|
||||
fileDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
contextDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
missingDependencies: new LazySet()
|
||||
};
|
||||
const resolver = compilation.resolverFactory.get(
|
||||
"normal",
|
||||
undefined,
|
||||
"esm"
|
||||
);
|
||||
|
||||
/**
|
||||
* @param {string} request imported request
|
||||
* @param {string} name overridable name
|
||||
* @param {OverridablesConfig} config config
|
||||
* @returns {Promise<void>} promise
|
||||
*/
|
||||
const resolveOverridable = (request, name, config) => {
|
||||
return new Promise(resolve => {
|
||||
resolver.resolve(
|
||||
{},
|
||||
compiler.context,
|
||||
request,
|
||||
resolveContext,
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
compilation.errors.push(
|
||||
new ModuleNotFoundError(null, err, {
|
||||
name: `overridable ${name}`
|
||||
})
|
||||
);
|
||||
return resolve();
|
||||
}
|
||||
resolvedOverridables.set(result, {
|
||||
name
|
||||
});
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
const promise = Promise.all(
|
||||
this._overridables.map(([name, config]) => {
|
||||
return Promise.all(
|
||||
config.import.map(request =>
|
||||
resolveOverridable(request, name, config)
|
||||
)
|
||||
);
|
||||
})
|
||||
).then(() => {
|
||||
compilation.contextDependencies.addAll(
|
||||
resolveContext.contextDependencies
|
||||
);
|
||||
compilation.fileDependencies.addAll(resolveContext.fileDependencies);
|
||||
compilation.missingDependencies.addAll(
|
||||
resolveContext.missingDependencies
|
||||
);
|
||||
});
|
||||
normalModuleFactory.hooks.afterResolve.tapAsync(
|
||||
PLUGIN_NAME,
|
||||
(resolveData, callback) => {
|
||||
// wait for resolving to be complete
|
||||
promise.then(() => callback());
|
||||
}
|
||||
);
|
||||
normalModuleFactory.hooks.module.tap(
|
||||
PLUGIN_NAME,
|
||||
(module, createData, resolveData) => {
|
||||
if (
|
||||
resolveData.dependencies[0] instanceof
|
||||
OverridableOriginalDependency
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const options = resolvedOverridables.get(createData.resource);
|
||||
if (options !== undefined) {
|
||||
return new OverridableModule(
|
||||
resolveData.context,
|
||||
resolveData.request,
|
||||
options
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
PLUGIN_NAME,
|
||||
(chunk, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.moduleFactories);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new OverridablesRuntimeModule(set)
|
||||
);
|
||||
}
|
||||
);
|
||||
const handler = parser => {
|
||||
parser.hooks.expression
|
||||
.for("__webpack_override__")
|
||||
.tap(
|
||||
PLUGIN_NAME,
|
||||
toConstantDependency(
|
||||
parser,
|
||||
`Object.assign.bind(Object, ${RuntimeGlobals.overrides})`,
|
||||
[RuntimeGlobals.overrides]
|
||||
)
|
||||
);
|
||||
parser.hooks.evaluateTypeof
|
||||
.for("__webpack_override__")
|
||||
.tap(PLUGIN_NAME, evaluateToString("function"));
|
||||
};
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/auto")
|
||||
.tap("APIPlugin", handler);
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/dynamic")
|
||||
.tap("APIPlugin", handler);
|
||||
normalModuleFactory.hooks.parser
|
||||
.for("javascript/esm")
|
||||
.tap("APIPlugin", handler);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OverridablesPlugin;
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
const Template = require("../Template");
|
||||
|
||||
/** @typedef {import("./OverridableModule")} OverridableModule */
|
||||
|
||||
class OverridablesRuntimeModule extends RuntimeModule {
|
||||
constructor(runtimeRequirements) {
|
||||
super("overridables");
|
||||
this._runtimeRequirements = runtimeRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const {
|
||||
runtimeTemplate,
|
||||
moduleGraph,
|
||||
chunkGraph,
|
||||
codeGenerationResults
|
||||
} = this.compilation;
|
||||
const chunkToOverridableMapping = {};
|
||||
const idToNameMapping = {};
|
||||
const overridableToFallbackMapping = new Map();
|
||||
const initialOverridables = {};
|
||||
const asyncChunks = this.chunk.getAllAsyncChunks();
|
||||
for (const chunk of asyncChunks) {
|
||||
const modules = chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"overridable"
|
||||
);
|
||||
if (!modules) continue;
|
||||
const overridables = (chunkToOverridableMapping[chunk.id] = []);
|
||||
for (const m of modules) {
|
||||
const module = /** @type {OverridableModule} */ (m);
|
||||
const name = module.options.name;
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
overridables.push(id);
|
||||
idToNameMapping[id] = name;
|
||||
const source = codeGenerationResults
|
||||
.get(module)
|
||||
.sources.get("overridable");
|
||||
overridableToFallbackMapping.set(id, source.source());
|
||||
}
|
||||
}
|
||||
for (const chunk of this.chunk.getAllReferencedChunks()) {
|
||||
if (asyncChunks.has(chunk)) continue;
|
||||
const modules = chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"overridable"
|
||||
);
|
||||
if (!modules) continue;
|
||||
for (const m of modules) {
|
||||
const module = /** @type {OverridableModule} */ (m);
|
||||
const name = module.options.name;
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
idToNameMapping[id] = name;
|
||||
const fallbackModule = moduleGraph.getModule(
|
||||
module.blocks[0].dependencies[0]
|
||||
);
|
||||
const fallbackId = chunkGraph.getModuleId(fallbackModule);
|
||||
initialOverridables[id] = fallbackId;
|
||||
}
|
||||
}
|
||||
return Template.asString([
|
||||
`${RuntimeGlobals.overrides} = {};`,
|
||||
"var installedModules = {};",
|
||||
`var idToNameMapping = ${JSON.stringify(idToNameMapping, null, "\t")};`,
|
||||
|
||||
Object.keys(initialOverridables).length
|
||||
? Template.asString([
|
||||
`var initialOverridables = ${JSON.stringify(
|
||||
initialOverridables,
|
||||
null,
|
||||
"\t"
|
||||
)};`,
|
||||
`for(var id in initialOverridables) if(${
|
||||
RuntimeGlobals.hasOwnProperty
|
||||
}(initialOverridables, id)) __webpack_modules__[id] = (${runtimeTemplate.returningFunction(
|
||||
`${runtimeTemplate.basicFunction("module", [
|
||||
"// Handle case when module is used sync",
|
||||
"installedModules[id] = 0;",
|
||||
`var override = ${RuntimeGlobals.overrides}[idToNameMapping[id]];`,
|
||||
"module.exports = override ? override()() : __webpack_require__(initialOverridables[id]);"
|
||||
])}`,
|
||||
"id"
|
||||
)})(id);`
|
||||
])
|
||||
: "// no overridables in initial chunks",
|
||||
this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
|
||||
? Template.asString([
|
||||
`var chunkMapping = ${JSON.stringify(
|
||||
chunkToOverridableMapping,
|
||||
null,
|
||||
"\t"
|
||||
)};`,
|
||||
"var fallbackMapping = {",
|
||||
Template.indent(
|
||||
Array.from(
|
||||
overridableToFallbackMapping,
|
||||
([id, source]) =>
|
||||
`${JSON.stringify(id)}: ${runtimeTemplate.basicFunction(
|
||||
"",
|
||||
source
|
||||
)}`
|
||||
).join(",\n")
|
||||
),
|
||||
"};",
|
||||
`${
|
||||
RuntimeGlobals.ensureChunkHandlers
|
||||
}.overridables = ${runtimeTemplate.basicFunction(
|
||||
"chunkId, promises",
|
||||
[
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
|
||||
Template.indent([
|
||||
`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
|
||||
"id",
|
||||
[
|
||||
`promises.push(${
|
||||
RuntimeGlobals.hasOwnProperty
|
||||
}(installedModules, id) ? installedModules[id] : installedModules[id] = Promise.resolve((${
|
||||
RuntimeGlobals.overrides
|
||||
}[idToNameMapping[id]] || fallbackMapping[id])()).then(${runtimeTemplate.basicFunction(
|
||||
"factory",
|
||||
[
|
||||
"installedModules[id] = 0;",
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction(
|
||||
"module",
|
||||
["module.exports = factory();"]
|
||||
)}`
|
||||
]
|
||||
)}))`
|
||||
]
|
||||
)});`
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
)}`
|
||||
])
|
||||
: "// no chunk loading of overridables"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OverridablesRuntimeModule;
|
||||
|
|
@ -8,9 +8,8 @@
|
|||
const { RawSource } = require("webpack-sources");
|
||||
const Module = require("../Module");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const createHash = require("../util/createHash");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const RemoteOverridesDependency = require("./RemoteOverridesDependency");
|
||||
const FallbackDependency = require("./FallbackDependency");
|
||||
const RemoteToExternalDependency = require("./RemoteToExternalDependency");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
|
|
@ -26,33 +25,26 @@ const RemoteToExternalDependency = require("./RemoteToExternalDependency");
|
|||
/** @typedef {import("../WebpackError")} WebpackError */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
/** @typedef {import("./RemoteOverridesModule").OverrideOptions} OverrideOptions */
|
||||
|
||||
const TYPES = new Set(["remote"]);
|
||||
const TYPES = new Set(["remote", "share-init"]);
|
||||
const RUNTIME_REQUIREMENTS = new Set([RuntimeGlobals.module]);
|
||||
|
||||
class RemoteModule extends Module {
|
||||
/**
|
||||
* @param {string} request request string
|
||||
* @param {[string, OverrideOptions][]} overrides list of overrides
|
||||
* @param {string[]} externalRequests list of external requests to containers
|
||||
* @param {string} internalRequest name of exposed module in container
|
||||
* @param {string} shareScope the used share scope name
|
||||
*/
|
||||
constructor(request, overrides, externalRequests, internalRequest) {
|
||||
constructor(request, externalRequests, internalRequest, shareScope) {
|
||||
super("remote-module");
|
||||
this.request = request;
|
||||
this.overrides = overrides;
|
||||
this.externalRequests = externalRequests;
|
||||
this.internalRequest = internalRequest;
|
||||
const hash = createHash("md4");
|
||||
for (const [key, request] of overrides) {
|
||||
hash.update(key);
|
||||
hash.update(request.import);
|
||||
}
|
||||
this._overridesHash = hash.digest("hex");
|
||||
this._identifier = `remote ${this.externalRequests.join(" ")} ${
|
||||
this.internalRequest
|
||||
} ${this._overridesHash}`;
|
||||
this.shareScope = shareScope;
|
||||
this._identifier = `remote (${shareScope}) ${this.externalRequests.join(
|
||||
" "
|
||||
)} ${this.internalRequest}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -102,9 +94,13 @@ class RemoteModule extends Module {
|
|||
};
|
||||
|
||||
this.clearDependenciesAndBlocks();
|
||||
this.addDependency(new RemoteOverridesDependency(this.overrides));
|
||||
for (const externalRequest of this.externalRequests)
|
||||
this.addDependency(new RemoteToExternalDependency(externalRequest));
|
||||
if (this.externalRequests.length === 1) {
|
||||
this.addDependency(
|
||||
new RemoteToExternalDependency(this.externalRequests[0])
|
||||
);
|
||||
} else {
|
||||
this.addDependency(new FallbackDependency(this.externalRequests));
|
||||
}
|
||||
|
||||
callback();
|
||||
}
|
||||
|
|
@ -114,7 +110,7 @@ class RemoteModule extends Module {
|
|||
* @returns {number} the estimated size of the module (must be non-zero)
|
||||
*/
|
||||
size(type) {
|
||||
return 42;
|
||||
return 6;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,17 +132,27 @@ class RemoteModule extends Module {
|
|||
* @returns {CodeGenerationResult} result
|
||||
*/
|
||||
codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
|
||||
const module = moduleGraph.getModule(this.dependencies[0]);
|
||||
const id = module && chunkGraph.getModuleId(module);
|
||||
const sources = new Map();
|
||||
sources.set("remote", new RawSource(""));
|
||||
return { sources, runtimeRequirements: RUNTIME_REQUIREMENTS };
|
||||
const data = new Map();
|
||||
data.set("share-init", [
|
||||
{
|
||||
shareScope: this.shareScope,
|
||||
initStage: 20,
|
||||
init: id === undefined ? "" : `initExternal(${JSON.stringify(id)});`
|
||||
}
|
||||
]);
|
||||
return { sources, data, runtimeRequirements: RUNTIME_REQUIREMENTS };
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.request);
|
||||
write(this.overrides);
|
||||
write(this.externalRequests);
|
||||
write(this.internalRequest);
|
||||
write(this.shareScope);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Dependency = require("../Dependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
class RemoteOverridesDependency extends Dependency {
|
||||
constructor(overrides) {
|
||||
super();
|
||||
this.overrides = overrides;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "remote overrides";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `remote overrides ${this.overrides
|
||||
.map(([key, request]) => `${key}=${request}`)
|
||||
.join()}`;
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
context.write(this.overrides);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
this.overrides = context.read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
RemoteOverridesDependency,
|
||||
"webpack/lib/container/RemoteOverridesDependency"
|
||||
);
|
||||
|
||||
module.exports = RemoteOverridesDependency;
|
||||
|
|
@ -21,7 +21,6 @@ class RemoteRuntimeModule extends RuntimeModule {
|
|||
*/
|
||||
generate() {
|
||||
const { runtimeTemplate, chunkGraph, moduleGraph } = this.compilation;
|
||||
let hasFallback = false;
|
||||
const chunkToRemotesMapping = {};
|
||||
const idToExternalAndNameMapping = {};
|
||||
for (const chunk of this.chunk.getAllAsyncChunks()) {
|
||||
|
|
@ -35,20 +34,13 @@ class RemoteRuntimeModule extends RuntimeModule {
|
|||
const module = /** @type {RemoteModule} */ (m);
|
||||
const name = module.internalRequest;
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
const overridesModule = moduleGraph.getModule(module.dependencies[0]);
|
||||
const overridesModuleId =
|
||||
overridesModule && chunkGraph.getModuleId(overridesModule);
|
||||
const externalModuleIds = module.dependencies.slice(1).map(dep => {
|
||||
const externalModule = moduleGraph.getModule(dep);
|
||||
return externalModule && chunkGraph.getModuleId(externalModule);
|
||||
});
|
||||
if (externalModuleIds.length > 1) hasFallback = true;
|
||||
const shareScope = module.shareScope;
|
||||
const dep = module.dependencies[0];
|
||||
const externalModule = moduleGraph.getModule(dep);
|
||||
const externalModuleId =
|
||||
externalModule && chunkGraph.getModuleId(externalModule);
|
||||
remotes.push(id);
|
||||
idToExternalAndNameMapping[id] = [
|
||||
overridesModuleId,
|
||||
name,
|
||||
...externalModuleIds
|
||||
];
|
||||
idToExternalAndNameMapping[id] = [shareScope, name, externalModuleId];
|
||||
}
|
||||
}
|
||||
return Template.asString([
|
||||
|
|
@ -69,84 +61,58 @@ class RemoteRuntimeModule extends RuntimeModule {
|
|||
`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
|
||||
Template.indent([
|
||||
`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction("id", [
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return installedModules[id] && promises.push(installedModules[id]);`,
|
||||
`if(installedModules[id]) return promises.push(installedModules[id]);`,
|
||||
"var data = idToExternalAndNameMapping[id];",
|
||||
`var onError = ${runtimeTemplate.basicFunction("error", [
|
||||
'if(!error) error = new Error("Container missing");',
|
||||
'if(typeof error.message === "string")',
|
||||
Template.indent(
|
||||
`error.message += '\\nwhile loading "' + data[1] + '" from ' + data[${
|
||||
hasFallback ? "i" : "2"
|
||||
}];`
|
||||
`error.message += '\\nwhile loading "' + data[1] + '" from ' + data[2];`
|
||||
),
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction("", [
|
||||
"throw error;"
|
||||
])}`,
|
||||
"delete installedModules[id];"
|
||||
"installedModules[id] = 0;"
|
||||
])};`,
|
||||
`var onExternal = ${runtimeTemplate.basicFunction(
|
||||
"external, handlePromise",
|
||||
`var handleFunction = ${runtimeTemplate.basicFunction(
|
||||
"fn, key, data, next, first",
|
||||
[
|
||||
"try {",
|
||||
Template.indent([
|
||||
"var promise = __webpack_require__(data[0])(external).get(data[1]);",
|
||||
"var promise = fn(key, data);",
|
||||
"if(promise && promise.then) {",
|
||||
Template.indent([
|
||||
"var p = promise.then(onFactory, onError);",
|
||||
`if(handlePromise) promises.push(installedModules[id] = p); else return p;`
|
||||
`var p = promise.then(${runtimeTemplate.returningFunction(
|
||||
"next(result, data)",
|
||||
"result"
|
||||
)}, onError);`,
|
||||
`if(first) promises.push(installedModules[id] = p); else return p;`
|
||||
]),
|
||||
"} else {",
|
||||
Template.indent([`onFactory(promise);`]),
|
||||
Template.indent(["return next(promise, data, first);"]),
|
||||
"}"
|
||||
]),
|
||||
"} catch(error) {",
|
||||
Template.indent(["onError(error);"]),
|
||||
"}"
|
||||
]
|
||||
)}`,
|
||||
`var onExternal = ${runtimeTemplate.returningFunction(
|
||||
`external ? handleFunction(${RuntimeGlobals.initializeSharing}, data[0], external, onInitialized, first) : onError()`,
|
||||
"external, _, first"
|
||||
)};`,
|
||||
`var onInitialized = ${runtimeTemplate.returningFunction(
|
||||
`handleFunction(external.get, data[1], external, onFactory, first)`,
|
||||
"_, external, first"
|
||||
)};`,
|
||||
`var onFactory = ${runtimeTemplate.basicFunction("factory", [
|
||||
"installedModules[id] = 0;",
|
||||
"installedModules[id] = 1;",
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction(
|
||||
"module",
|
||||
["module.exports = factory();"]
|
||||
)}`
|
||||
])};`,
|
||||
hasFallback
|
||||
? Template.asString([
|
||||
"var i = 1, item, result;",
|
||||
"(function next(error) {",
|
||||
Template.indent([
|
||||
"for(;;) {",
|
||||
Template.indent([
|
||||
"try {",
|
||||
Template.indent([
|
||||
"// Process with the next external in the data array",
|
||||
"item = data[++i];",
|
||||
"// Reached end of data, report the last error",
|
||||
"if(!item) return onError(error);",
|
||||
"result = __webpack_require__(item);",
|
||||
"// Continue when receiving falsy value, otherwise handle promise or normal value",
|
||||
"if(result) return result.then ? promises.push(installedModules[id] = result.then(onExternal, next)) : onExternal(result, 1);"
|
||||
]),
|
||||
"} catch(e) {",
|
||||
Template.indent("error = e;"),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"})();"
|
||||
])
|
||||
: Template.asString([
|
||||
"try {",
|
||||
Template.indent([
|
||||
"var promise =__webpack_require__(data[2]);",
|
||||
"if(promise) return promise.then ? promises.push(installedModules[id] = promise.then(onExternal, onError)) : onExternal(promise, 1);",
|
||||
"onError();"
|
||||
]),
|
||||
"} catch(error) {",
|
||||
Template.indent(["onError(error);"]),
|
||||
"}"
|
||||
])
|
||||
"handleFunction(__webpack_require__, data[2], 1, onExternal, 1);"
|
||||
])});`
|
||||
]),
|
||||
"}"
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
* @template T
|
||||
* @template N
|
||||
* @param {ContainerOptionsFormat<T>} options options passed by the user
|
||||
* @param {function(string | string[]) : N} normalizeSimple normalize a simple item
|
||||
* @param {function(T) : N} normalizeOptions normalize a complex item
|
||||
* @param {function(string | string[], string) : N} normalizeSimple normalize a simple item
|
||||
* @param {function(T, string) : N} normalizeOptions normalize a complex item
|
||||
* @param {function(string, N): void} fn processing function
|
||||
* @returns {void}
|
||||
*/
|
||||
|
|
@ -20,7 +20,7 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
|
|||
const array = items => {
|
||||
for (const item of items) {
|
||||
if (typeof item === "string") {
|
||||
fn(item, normalizeSimple(item));
|
||||
fn(item, normalizeSimple(item, item));
|
||||
} else if (item && typeof item === "object") {
|
||||
object(item);
|
||||
} else {
|
||||
|
|
@ -31,9 +31,9 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
|
|||
const object = obj => {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
if (typeof value === "string" || Array.isArray(value)) {
|
||||
fn(key, normalizeSimple(value));
|
||||
fn(key, normalizeSimple(value, key));
|
||||
} else {
|
||||
fn(key, normalizeOptions(value));
|
||||
fn(key, normalizeOptions(value, key));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -52,8 +52,8 @@ const process = (options, normalizeSimple, normalizeOptions, fn) => {
|
|||
* @template T
|
||||
* @template R
|
||||
* @param {ContainerOptionsFormat<T>} options options passed by the user
|
||||
* @param {function(string | string[]) : R} normalizeSimple normalize a simple item
|
||||
* @param {function(T) : R} normalizeOptions normalize a complex item
|
||||
* @param {function(string | string[], string) : R} normalizeSimple normalize a simple item
|
||||
* @param {function(T, string) : R} normalizeOptions normalize a complex item
|
||||
* @returns {[string, R][]} parsed options
|
||||
*/
|
||||
const parseOptions = (options, normalizeSimple, normalizeOptions) => {
|
||||
|
|
|
|||
16
lib/index.js
16
lib/index.js
|
|
@ -390,8 +390,20 @@ module.exports = mergeExports(fn, {
|
|||
get ModuleFederationPlugin() {
|
||||
return require("./container/ModuleFederationPlugin");
|
||||
},
|
||||
get OverridablesPlugin() {
|
||||
return require("./container/OverridablesPlugin");
|
||||
get scope() {
|
||||
return require("./container/options").scope;
|
||||
}
|
||||
},
|
||||
|
||||
sharing: {
|
||||
get ConsumeSharedPlugin() {
|
||||
return require("./sharing/ConsumeSharedPlugin");
|
||||
},
|
||||
get ProvideSharedPlugin() {
|
||||
return require("./sharing/ProvideSharedPlugin");
|
||||
},
|
||||
get SharePlugin() {
|
||||
return require("./sharing/SharePlugin");
|
||||
},
|
||||
get scope() {
|
||||
return require("./container/options").scope;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const ModuleDependency = require("../dependencies/ModuleDependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
class ConsumeFallbackDependency extends ModuleDependency {
|
||||
constructor(request) {
|
||||
super(request);
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "consume fallback";
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
ConsumeFallbackDependency,
|
||||
"webpack/lib/sharing/ConsumeFallbackDependency"
|
||||
);
|
||||
|
||||
module.exports = ConsumeFallbackDependency;
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { RawSource } = require("webpack-sources");
|
||||
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
||||
const Module = require("../Module");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const ConsumeFallbackDependency = require("./ConsumeFallbackDependency");
|
||||
const { versionToString } = require("./utils");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("../ChunkGraph")} ChunkGraph */
|
||||
/** @typedef {import("../ChunkGroup")} ChunkGroup */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
/** @typedef {import("../Module").CodeGenerationContext} CodeGenerationContext */
|
||||
/** @typedef {import("../Module").CodeGenerationResult} CodeGenerationResult */
|
||||
/** @typedef {import("../Module").LibIdentOptions} LibIdentOptions */
|
||||
/** @typedef {import("../Module").NeedBuildContext} NeedBuildContext */
|
||||
/** @typedef {import("../RequestShortener")} RequestShortener */
|
||||
/** @typedef {import("../ResolverFactory").ResolverWithOptions} ResolverWithOptions */
|
||||
/** @typedef {import("../WebpackError")} WebpackError */
|
||||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ConsumeOptions
|
||||
* @property {string=} import fallback request
|
||||
* @property {string} shareKey global share key
|
||||
* @property {string} shareScope share scope
|
||||
* @property {(number|string)[]} requiredVersion version requirement
|
||||
* @property {boolean} strictVersion don't use shared version even if version isn't valid
|
||||
* @property {boolean} singleton use single global version
|
||||
* @property {boolean} eager include the fallback module in a sync way
|
||||
*/
|
||||
|
||||
const TYPES = new Set(["consume-shared"]);
|
||||
|
||||
class ConsumeSharedModule extends Module {
|
||||
/**
|
||||
* @param {string} context context
|
||||
* @param {ConsumeOptions} options consume options
|
||||
*/
|
||||
constructor(context, options) {
|
||||
super("consume-shared-module", context);
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} a unique identifier of the module
|
||||
*/
|
||||
identifier() {
|
||||
const {
|
||||
shareKey,
|
||||
shareScope,
|
||||
import: request,
|
||||
requiredVersion,
|
||||
strictVersion,
|
||||
singleton,
|
||||
eager
|
||||
} = this.options;
|
||||
return `consume-shared-module|${shareScope}|${shareKey}|${versionToString(
|
||||
requiredVersion
|
||||
)}|${strictVersion}|${request}|${singleton}|${eager}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {RequestShortener} requestShortener the request shortener
|
||||
* @returns {string} a user readable identifier of the module
|
||||
*/
|
||||
readableIdentifier(requestShortener) {
|
||||
const {
|
||||
shareKey,
|
||||
shareScope,
|
||||
import: request,
|
||||
requiredVersion,
|
||||
strictVersion,
|
||||
singleton,
|
||||
eager
|
||||
} = this.options;
|
||||
return `shared module (${shareScope}) ${shareKey}@${versionToString(
|
||||
requiredVersion
|
||||
)}${strictVersion ? " (strict)" : ""}${singleton ? " (singleton)" : ""}${
|
||||
request ? ` -> ${request}` : ""
|
||||
}${eager ? " (eager)" : ""}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {LibIdentOptions} options options
|
||||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
const { shareKey, shareScope, import: request } = this.options;
|
||||
return `webpack/sharing/consume/${shareScope}/${shareKey}${
|
||||
request ? `/${request}` : ""
|
||||
}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {NeedBuildContext} context context info
|
||||
* @param {function(WebpackError=, boolean=): void} callback callback function, returns true, if the module needs a rebuild
|
||||
* @returns {void}
|
||||
*/
|
||||
needBuild(context, callback) {
|
||||
callback(null, !this.buildInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {WebpackOptions} options webpack options
|
||||
* @param {Compilation} compilation the compilation
|
||||
* @param {ResolverWithOptions} resolver the resolver
|
||||
* @param {InputFileSystem} fs the file system
|
||||
* @param {function(WebpackError=): void} callback callback function
|
||||
* @returns {void}
|
||||
*/
|
||||
build(options, compilation, resolver, fs, callback) {
|
||||
this.buildMeta = {};
|
||||
this.buildInfo = {};
|
||||
if (this.options.import) {
|
||||
const dep = new ConsumeFallbackDependency(this.options.import);
|
||||
if (this.options.eager) {
|
||||
this.addDependency(dep);
|
||||
} else {
|
||||
const block = new AsyncDependenciesBlock({});
|
||||
block.addDependency(dep);
|
||||
this.addBlock(block);
|
||||
}
|
||||
}
|
||||
callback();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Set<string>} types available (do not mutate)
|
||||
*/
|
||||
getSourceTypes() {
|
||||
return TYPES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string=} type the source type for which the size should be estimated
|
||||
* @returns {number} the estimated size of the module (must be non-zero)
|
||||
*/
|
||||
size(type) {
|
||||
return 42;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Hash} hash the hash used to track dependencies
|
||||
* @param {ChunkGraph} chunkGraph the chunk graph
|
||||
* @returns {void}
|
||||
*/
|
||||
updateHash(hash, chunkGraph) {
|
||||
hash.update(JSON.stringify(this.options));
|
||||
super.updateHash(hash, chunkGraph);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CodeGenerationContext} context context for code generation
|
||||
* @returns {CodeGenerationResult} result
|
||||
*/
|
||||
codeGeneration({ chunkGraph, moduleGraph, runtimeTemplate }) {
|
||||
const runtimeRequirements = new Set([RuntimeGlobals.shareScopeMap]);
|
||||
const {
|
||||
shareScope,
|
||||
shareKey,
|
||||
strictVersion,
|
||||
requiredVersion,
|
||||
import: request,
|
||||
singleton,
|
||||
eager
|
||||
} = this.options;
|
||||
let fallbackCode;
|
||||
if (request) {
|
||||
if (eager) {
|
||||
const dep = this.dependencies[0];
|
||||
fallbackCode = runtimeTemplate.syncModuleFactory({
|
||||
dependency: dep,
|
||||
chunkGraph,
|
||||
runtimeRequirements,
|
||||
request: this.options.import
|
||||
});
|
||||
} else {
|
||||
const block = this.blocks[0];
|
||||
fallbackCode = runtimeTemplate.asyncModuleFactory({
|
||||
block,
|
||||
chunkGraph,
|
||||
runtimeRequirements,
|
||||
request: this.options.import
|
||||
});
|
||||
}
|
||||
}
|
||||
let fn = "load";
|
||||
const args = [JSON.stringify(shareScope), JSON.stringify(shareKey)];
|
||||
if (requiredVersion) {
|
||||
if (strictVersion) {
|
||||
fn += "Strict";
|
||||
}
|
||||
if (singleton) {
|
||||
fn += "Singleton";
|
||||
}
|
||||
args.push(JSON.stringify(requiredVersion));
|
||||
fn += "VersionCheck";
|
||||
}
|
||||
if (fallbackCode) {
|
||||
fn += "Fallback";
|
||||
args.push(fallbackCode);
|
||||
}
|
||||
const code = runtimeTemplate.returningFunction(`${fn}(${args.join(", ")})`);
|
||||
const sources = new Map();
|
||||
sources.set("consume-shared", new RawSource(code));
|
||||
return {
|
||||
runtimeRequirements,
|
||||
sources
|
||||
};
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this.options);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
deserialize(context) {
|
||||
const { read } = context;
|
||||
this.options = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
ConsumeSharedModule,
|
||||
"webpack/lib/sharing/ConsumeSharedModule"
|
||||
);
|
||||
|
||||
module.exports = ConsumeSharedModule;
|
||||
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../../schemas/plugins/sharing/ConsumeSharedPlugin.json");
|
||||
const ModuleNotFoundError = require("../ModuleNotFoundError");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const { parseOptions } = require("../container/options");
|
||||
const LazySet = require("../util/LazySet");
|
||||
const ConsumeFallbackDependency = require("./ConsumeFallbackDependency");
|
||||
const ConsumeSharedModule = require("./ConsumeSharedModule");
|
||||
const ConsumeSharedRuntimeModule = require("./ConsumeSharedRuntimeModule");
|
||||
const ProvidedDependency = require("./ProvidedDependency");
|
||||
const { parseRequiredVersion, isRequiredVersion } = require("./utils");
|
||||
|
||||
/** @typedef {import("enhanced-resolve").ResolveContext} ResolveContext */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions} ConsumeSharedPluginOptions */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("./ConsumeSharedModule").ConsumeOptions} ConsumeOptions */
|
||||
|
||||
const PLUGIN_NAME = "ConsumeSharedPlugin";
|
||||
|
||||
class ConsumeSharedPlugin {
|
||||
/**
|
||||
* @param {ConsumeSharedPluginOptions} options options
|
||||
*/
|
||||
constructor(options) {
|
||||
if (typeof options !== "string") {
|
||||
validateOptions(schema, options, { name: "Consumes Shared Plugin" });
|
||||
}
|
||||
|
||||
/** @type {[string, ConsumeOptions][]} */
|
||||
this._consumes = parseOptions(
|
||||
options.consumes,
|
||||
(item, key) => {
|
||||
if (Array.isArray(item)) throw new Error("Unexpected array in options");
|
||||
/** @type {ConsumeOptions} */
|
||||
let result =
|
||||
item === key || !isRequiredVersion(item)
|
||||
? // item is a request/key
|
||||
{
|
||||
import: key,
|
||||
shareScope: options.shareScope || "default",
|
||||
shareKey: key,
|
||||
requiredVersion: undefined,
|
||||
strictVersion: false,
|
||||
singleton: false,
|
||||
eager: false
|
||||
}
|
||||
: // key is a request/key
|
||||
// item is a version
|
||||
{
|
||||
import: key,
|
||||
shareScope: options.shareScope || "default",
|
||||
shareKey: key,
|
||||
requiredVersion: parseRequiredVersion(item),
|
||||
strictVersion: true,
|
||||
singleton: false,
|
||||
eager: false
|
||||
};
|
||||
return result;
|
||||
},
|
||||
(item, key) => ({
|
||||
import: item.import === false ? undefined : item.import || key,
|
||||
shareScope: item.shareScope || options.shareScope || "default",
|
||||
shareKey: item.shareKey || key,
|
||||
requiredVersion:
|
||||
typeof item.requiredVersion === "string"
|
||||
? parseRequiredVersion(item.requiredVersion)
|
||||
: item.requiredVersion,
|
||||
strictVersion:
|
||||
item.requiredVersion &&
|
||||
(typeof item.strictVersion === "boolean"
|
||||
? item.strictVersion
|
||||
: item.import !== false && !item.singleton),
|
||||
singleton: !!item.singleton,
|
||||
eager: !!item.eager
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
compiler.hooks.thisCompilation.tap(
|
||||
PLUGIN_NAME,
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
compilation.dependencyFactories.set(
|
||||
ConsumeFallbackDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
/** @type {Map<string, ConsumeOptions>} */
|
||||
const resolvedConsumes = new Map();
|
||||
/** @type {Map<string, ConsumeOptions>} */
|
||||
const unresolvedConsumes = new Map();
|
||||
/** @type {Map<string, ConsumeOptions>} */
|
||||
const prefixConsumes = new Map();
|
||||
const resolveContext = {
|
||||
/** @type {LazySet<string>} */
|
||||
fileDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
contextDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
missingDependencies: new LazySet()
|
||||
};
|
||||
const resolver = compilation.resolverFactory.get("normal");
|
||||
/**
|
||||
* @param {string} request imported request
|
||||
* @param {ConsumeOptions} options options
|
||||
* @returns {Promise<void>} promise
|
||||
*/
|
||||
const resolveConsume = (request, options) => {
|
||||
if (/^\.\.?(\/|$)/.test(request)) {
|
||||
// relative request
|
||||
return new Promise(resolve => {
|
||||
resolver.resolve(
|
||||
{},
|
||||
compiler.context,
|
||||
request,
|
||||
resolveContext,
|
||||
(err, result) => {
|
||||
if (err) {
|
||||
compilation.errors.push(
|
||||
new ModuleNotFoundError(null, err, {
|
||||
name: `consumed shared module ${request}`
|
||||
})
|
||||
);
|
||||
return resolve();
|
||||
}
|
||||
resolvedConsumes.set(result, options);
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
} else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) {
|
||||
// absolute path
|
||||
resolvedConsumes.set(request, options);
|
||||
} else if (request.endsWith("/")) {
|
||||
// module request prefix
|
||||
prefixConsumes.set(request, options);
|
||||
} else {
|
||||
// module request
|
||||
unresolvedConsumes.set(request, options);
|
||||
}
|
||||
};
|
||||
const promise = Promise.all(
|
||||
this._consumes.map(([name, config]) => resolveConsume(name, config))
|
||||
).then(() => {
|
||||
compilation.contextDependencies.addAll(
|
||||
resolveContext.contextDependencies
|
||||
);
|
||||
compilation.fileDependencies.addAll(resolveContext.fileDependencies);
|
||||
compilation.missingDependencies.addAll(
|
||||
resolveContext.missingDependencies
|
||||
);
|
||||
});
|
||||
normalModuleFactory.hooks.factorize.tapPromise(
|
||||
PLUGIN_NAME,
|
||||
({ context, request, dependencies }) =>
|
||||
// wait for resolving to be complete
|
||||
promise.then(() => {
|
||||
if (
|
||||
dependencies[0] instanceof ConsumeFallbackDependency ||
|
||||
dependencies[0] instanceof ProvidedDependency
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const match = unresolvedConsumes.get(request);
|
||||
if (match !== undefined) {
|
||||
return new ConsumeSharedModule(compiler.context, match);
|
||||
}
|
||||
for (const [prefix, options] of prefixConsumes) {
|
||||
if (request.startsWith(prefix)) {
|
||||
const remainder = request.slice(prefix.length);
|
||||
return new ConsumeSharedModule(compiler.context, {
|
||||
...options,
|
||||
import: options.import
|
||||
? options.import + remainder
|
||||
: undefined,
|
||||
shareKey: options.shareKey + remainder
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
normalModuleFactory.hooks.module.tap(
|
||||
PLUGIN_NAME,
|
||||
(module, createData, { context, request, dependencies }) => {
|
||||
if (
|
||||
dependencies[0] instanceof ConsumeFallbackDependency ||
|
||||
dependencies[0] instanceof ProvidedDependency
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const options = resolvedConsumes.get(createData.resource);
|
||||
if (options !== undefined) {
|
||||
return new ConsumeSharedModule(compiler.context, options);
|
||||
}
|
||||
}
|
||||
);
|
||||
compilation.hooks.additionalTreeRuntimeRequirements.tap(
|
||||
PLUGIN_NAME,
|
||||
(chunk, set) => {
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.moduleFactoriesAddOnly);
|
||||
set.add(RuntimeGlobals.shareScopeMap);
|
||||
set.add(RuntimeGlobals.initializeSharing);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
compilation.addRuntimeModule(
|
||||
chunk,
|
||||
new ConsumeSharedRuntimeModule(set)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConsumeSharedPlugin;
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
const Template = require("../Template");
|
||||
|
||||
/** @typedef {import("./ConsumeSharedModule")} ConsumeSharedModule */
|
||||
|
||||
class ConsumeSharedRuntimeModule extends RuntimeModule {
|
||||
constructor(runtimeRequirements) {
|
||||
super("consumes", 10);
|
||||
this._runtimeRequirements = runtimeRequirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const {
|
||||
runtimeTemplate,
|
||||
chunkGraph,
|
||||
codeGenerationResults
|
||||
} = this.compilation;
|
||||
const chunkToModuleMapping = {};
|
||||
const idToModuleMapping = new Map();
|
||||
const initialConsumes = [];
|
||||
for (const chunk of this.chunk.getAllAsyncChunks()) {
|
||||
const modules = chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"consume-shared"
|
||||
);
|
||||
if (!modules) continue;
|
||||
const consumes = (chunkToModuleMapping[chunk.id] = []);
|
||||
for (const m of modules) {
|
||||
const module = /** @type {ConsumeSharedModule} */ (m);
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
consumes.push(id);
|
||||
idToModuleMapping.set(id, module);
|
||||
}
|
||||
}
|
||||
for (const chunk of this.chunk.getAllInitialChunks()) {
|
||||
const modules = chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"consume-shared"
|
||||
);
|
||||
if (!modules) continue;
|
||||
for (const m of modules) {
|
||||
const module = /** @type {ConsumeSharedModule} */ (m);
|
||||
const id = chunkGraph.getModuleId(module);
|
||||
initialConsumes.push(id);
|
||||
idToModuleMapping.set(id, module);
|
||||
}
|
||||
}
|
||||
if (idToModuleMapping.size === 0) return null;
|
||||
return Template.asString([
|
||||
`var ensureExistence = ${runtimeTemplate.basicFunction(
|
||||
"scope, scopeName, key",
|
||||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) throw new Error("Shared module " + key + " doesn't exist in shared scope " + scopeName);`
|
||||
)};`,
|
||||
`var invalidVersion = ${runtimeTemplate.basicFunction(
|
||||
"version, requiredVersion",
|
||||
[
|
||||
"for(var i = 0; i < requiredVersion.length; i++) {",
|
||||
Template.indent([
|
||||
"if(i === version.length) return 1;",
|
||||
"if(version[i] != requiredVersion[i]) { // loose equal is intentional to match string and number",
|
||||
Template.indent([
|
||||
'if(typeof version[i] === "string" || typeof requiredVersion[i] === "string" || version[i] < requiredVersion[i]) return 1;',
|
||||
"if(version[i] > requiredVersion[i]) return;"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}"
|
||||
]
|
||||
)};`,
|
||||
`var checkSingletonVersion = ${runtimeTemplate.basicFunction(
|
||||
"key, version, requiredVersion, strict",
|
||||
[
|
||||
"if(!invalidVersion(version, requiredVersion)) return 1;",
|
||||
'var msg = "Unsatisfied version of shared singleton module " + key + "@" + (version && version.join(".")) + " (required " + key + "@" + requiredVersion.join(".") + ")";',
|
||||
"if(strict) throw new Error(msg);",
|
||||
'typeof console !== "undefined" && console.warn && console.warn(msg);'
|
||||
]
|
||||
)};`,
|
||||
`var findVersion = ${runtimeTemplate.basicFunction(
|
||||
"scope, key, requiredVersion, strict",
|
||||
[
|
||||
"requiredVersion = requiredVersion || [];",
|
||||
"var currentName = key;",
|
||||
`var versions = requiredVersion.map(${runtimeTemplate.returningFunction(
|
||||
'currentName += "`" + v',
|
||||
"v"
|
||||
)});`,
|
||||
"versions.unshift(key);",
|
||||
"var lastVersion;",
|
||||
"while(currentName = versions.shift()) {",
|
||||
Template.indent([
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(scope, currentName) && !invalidVersion(lastVersion = scope[currentName].version || [], requiredVersion)) return scope[currentName];`
|
||||
]),
|
||||
"}",
|
||||
'var msg = "Unsatisfied version of shared module " + key + "@" + (lastVersion && lastVersion.join(".")) + " (required " + key + "@" + requiredVersion.join(".") + ")";',
|
||||
"if(strict) throw new Error(msg);",
|
||||
'typeof console !== "undefined" && console.warn && console.warn(msg);'
|
||||
]
|
||||
)};`,
|
||||
`var get = ${runtimeTemplate.returningFunction(
|
||||
"(sharedModule.loaded = 1, sharedModule.get())",
|
||||
"sharedModule"
|
||||
)};`,
|
||||
`var load = ${runtimeTemplate.basicFunction("scopeName, key", [
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
`ensureExistence(scope, scopeName, key);`,
|
||||
"return get(scope[key]);"
|
||||
])};`,
|
||||
`var loadFallback = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, fallback",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
`return scope && ${RuntimeGlobals.hasOwnProperty}(scope, key) ? get(scope[key]) : fallback();`
|
||||
]
|
||||
)};`,
|
||||
`var loadVersionCheck = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
"ensureExistence(scope, scopeName, key);",
|
||||
"return get(findVersion(scope, key, version) || scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
`var loadSingletonVersionCheck = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
"ensureExistence(scope, scopeName, key);",
|
||||
"checkSingletonVersion(key, scope[key].version, version);",
|
||||
"return get(scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
`var loadStrictVersionCheck = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
"ensureExistence(scope, scopeName, key);",
|
||||
"return get(findVersion(scope, key, version, 1));"
|
||||
]
|
||||
)};`,
|
||||
`var loadStrictSingletonVersionCheck = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
"ensureExistence(scope, scopeName, key);",
|
||||
"checkSingletonVersion(key, scope[key].version, version, 1);",
|
||||
"return get(scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
`var loadVersionCheckFallback = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version, fallback",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
|
||||
"return get(findVersion(scope, key, version) || scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
`var loadSingletonVersionCheckFallback = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version, fallback",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
|
||||
"checkSingletonVersion(key, scope[key].version, version);",
|
||||
"return get(scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
`var loadStrictVersionCheckFallback = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version, fallback",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
"var entry = scope && findVersion(scope, key, version);",
|
||||
`return entry ? get(entry) : fallback();`
|
||||
]
|
||||
)};`,
|
||||
`var loadStrictSingletonVersionCheckFallback = ${runtimeTemplate.basicFunction(
|
||||
"scopeName, key, version, fallback",
|
||||
[
|
||||
`${RuntimeGlobals.initializeSharing}(scopeName);`,
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[scopeName];`,
|
||||
`if(!scope || !${RuntimeGlobals.hasOwnProperty}(scope, key)) return fallback();`,
|
||||
"checkSingletonVersion(key, scope[key].version, version, 1);",
|
||||
"return get(scope[key]);"
|
||||
]
|
||||
)};`,
|
||||
"var installedModules = {};",
|
||||
"var moduleToHandlerMapping = {",
|
||||
Template.indent(
|
||||
Array.from(
|
||||
idToModuleMapping,
|
||||
([key, module]) =>
|
||||
`${JSON.stringify(key)}: ${codeGenerationResults
|
||||
.get(module)
|
||||
.sources.get("consume-shared")
|
||||
.source()}`
|
||||
).join(",\n")
|
||||
),
|
||||
"};",
|
||||
|
||||
initialConsumes.length > 0
|
||||
? Template.asString([
|
||||
`var initialConsumes = ${JSON.stringify(initialConsumes)};`,
|
||||
`initialConsumes.forEach(${runtimeTemplate.basicFunction("id", [
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction(
|
||||
"module",
|
||||
[
|
||||
"// Handle case when module is used sync",
|
||||
"installedModules[id] = 0;",
|
||||
"delete __webpack_module_cache__[id];",
|
||||
"var factory = moduleToHandlerMapping[id]();",
|
||||
'if(typeof factory !== "function") throw new Error("Shared module is not available for eager consumption: " + id);',
|
||||
`module.exports = factory();`
|
||||
]
|
||||
)}`
|
||||
])});`
|
||||
])
|
||||
: "// no consumes in initial chunks",
|
||||
this._runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers)
|
||||
? Template.asString([
|
||||
`var chunkMapping = ${JSON.stringify(
|
||||
chunkToModuleMapping,
|
||||
null,
|
||||
"\t"
|
||||
)};`,
|
||||
`${
|
||||
RuntimeGlobals.ensureChunkHandlers
|
||||
}.consumes = ${runtimeTemplate.basicFunction("chunkId, promises", [
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(chunkMapping, chunkId)) {`,
|
||||
Template.indent([
|
||||
`chunkMapping[chunkId].forEach(${runtimeTemplate.basicFunction(
|
||||
"id",
|
||||
[
|
||||
`if(${RuntimeGlobals.hasOwnProperty}(installedModules, id)) return promises.push(installedModules[id]);`,
|
||||
`var onFactory = ${runtimeTemplate.basicFunction(
|
||||
"factory",
|
||||
[
|
||||
"installedModules[id] = 0;",
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction(
|
||||
"module",
|
||||
[
|
||||
"delete __webpack_module_cache__[id];",
|
||||
"module.exports = factory();"
|
||||
]
|
||||
)}`
|
||||
]
|
||||
)};`,
|
||||
`var onError = ${runtimeTemplate.basicFunction("error", [
|
||||
"delete installedModules[id];",
|
||||
`__webpack_modules__[id] = ${runtimeTemplate.basicFunction(
|
||||
"module",
|
||||
["delete __webpack_module_cache__[id];", "throw error;"]
|
||||
)}`
|
||||
])};`,
|
||||
"try {",
|
||||
Template.indent([
|
||||
"var promise = moduleToHandlerMapping[id]();",
|
||||
"if(promise.then) {",
|
||||
Template.indent(
|
||||
`promises.push(installedModules[id] = promise.then(onFactory).catch(onError));`
|
||||
),
|
||||
"} else onFactory(promise);"
|
||||
]),
|
||||
"} catch(e) { onError(e); }"
|
||||
]
|
||||
)});`
|
||||
]),
|
||||
"}"
|
||||
])}`
|
||||
])
|
||||
: "// no chunk loading of consumes"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConsumeSharedRuntimeModule;
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const Dependency = require("../Dependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
class ProvideDependency extends Dependency {
|
||||
constructor(shareScope, name, version, request, eager) {
|
||||
super();
|
||||
this.shareScope = shareScope;
|
||||
this.name = name;
|
||||
this.version = version;
|
||||
this.request = request;
|
||||
this.eager = eager;
|
||||
}
|
||||
|
||||
get type() {
|
||||
return "provide module";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `provide module (${this.shareScope}) ${this.request} as ${
|
||||
this.name
|
||||
} @ ${this.version}${this.eager ? " (eager)" : ""}`;
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
context.write(this.shareScope);
|
||||
context.write(this.name);
|
||||
context.write(this.request);
|
||||
context.write(this.version);
|
||||
context.write(this.eager);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
static deserialize(context) {
|
||||
const { read } = context;
|
||||
const obj = new ProvideDependency(read(), read(), read(), read(), read());
|
||||
this.shareScope = context.read();
|
||||
obj.deserialize(context);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(ProvideDependency, "webpack/lib/sharing/ProvideDependency");
|
||||
|
||||
module.exports = ProvideDependency;
|
||||
|
|
@ -5,14 +5,11 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
const { OriginalSource } = require("webpack-sources");
|
||||
const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
|
||||
const Module = require("../Module");
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const Template = require("../Template");
|
||||
const createHash = require("../util/createHash");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
const RemoteOverrideDependency = require("./RemoteOverrideDependency");
|
||||
const ProvidedDependency = require("./ProvidedDependency");
|
||||
|
||||
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
|
||||
/** @typedef {import("../Chunk")} Chunk */
|
||||
|
|
@ -29,37 +26,32 @@ const RemoteOverrideDependency = require("./RemoteOverrideDependency");
|
|||
/** @typedef {import("../util/Hash")} Hash */
|
||||
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
|
||||
|
||||
/**
|
||||
* @typedef {Object} OverrideOptions
|
||||
* @property {string} import request to new module
|
||||
*/
|
||||
const TYPES = new Set(["share-init"]);
|
||||
|
||||
const TYPES = new Set(["javascript"]);
|
||||
|
||||
class RemoteOverridesModule extends Module {
|
||||
class ProvideModule extends Module {
|
||||
/**
|
||||
* @param {[string, OverrideOptions][]} overrides list of overrides
|
||||
* @param {string} shareScope shared scope name
|
||||
* @param {string} name shared key
|
||||
* @param {(string | number)[]} version version
|
||||
* @param {string} request request to the provided module
|
||||
* @param {boolean} eager include the module in sync way
|
||||
*/
|
||||
constructor(overrides) {
|
||||
super("remote-overrides-module");
|
||||
this._overrides = overrides;
|
||||
if (overrides.length > 0) {
|
||||
const hash = createHash("md4");
|
||||
for (const [key, request] of overrides) {
|
||||
hash.update(key);
|
||||
hash.update(request.import);
|
||||
}
|
||||
this._overridesHash = hash.digest("hex");
|
||||
} else {
|
||||
this._overridesHash = "empty";
|
||||
}
|
||||
constructor(shareScope, name, version, request, eager) {
|
||||
super("provide-module");
|
||||
this._shareScope = shareScope;
|
||||
this._name = name;
|
||||
this._version = version;
|
||||
this._request = request;
|
||||
this._eager = eager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} a unique identifier of the module
|
||||
*/
|
||||
identifier() {
|
||||
return `remote overrides ${this._overridesHash}`;
|
||||
return `provide module (${this._shareScope}) ${this._name}@${
|
||||
this._version && this._version.join(".")
|
||||
} = ${this._request}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -67,9 +59,9 @@ class RemoteOverridesModule extends Module {
|
|||
* @returns {string} a user readable identifier of the module
|
||||
*/
|
||||
readableIdentifier(requestShortener) {
|
||||
return `remote overrides ${this._overrides
|
||||
.map(([key, request]) => `${key} = ${request}`)
|
||||
.join(", ")}`;
|
||||
return `provide module (${this._shareScope}) ${this._name}@${
|
||||
this._version && this._version.join(".")
|
||||
} = ${this._request}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,10 +69,7 @@ class RemoteOverridesModule extends Module {
|
|||
* @returns {string | null} an identifier for library inclusion
|
||||
*/
|
||||
libIdent(options) {
|
||||
return `webpack/container/remote-overrides/${this._overridesHash.slice(
|
||||
0,
|
||||
6
|
||||
)}`;
|
||||
return `webpack/sharing/provide/${this._shareScope}/${this._name}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -107,9 +96,11 @@ class RemoteOverridesModule extends Module {
|
|||
};
|
||||
|
||||
this.clearDependenciesAndBlocks();
|
||||
for (const [, options] of this._overrides) {
|
||||
const dep = new ProvidedDependency(this._request);
|
||||
if (this._eager) {
|
||||
this.addDependency(dep);
|
||||
} else {
|
||||
const block = new AsyncDependenciesBlock({});
|
||||
const dep = new RemoteOverrideDependency(options.import);
|
||||
block.addDependency(dep);
|
||||
this.addBlock(block);
|
||||
}
|
||||
|
|
@ -146,81 +137,54 @@ class RemoteOverridesModule extends Module {
|
|||
* @returns {CodeGenerationResult} result
|
||||
*/
|
||||
codeGeneration({ runtimeTemplate, moduleGraph, chunkGraph }) {
|
||||
const runtimeRequirements = new Set([RuntimeGlobals.module]);
|
||||
let i = 0;
|
||||
const source = Template.asString([
|
||||
`module.exports = ${runtimeTemplate.basicFunction(
|
||||
"external",
|
||||
this._overrides.length > 0
|
||||
? [
|
||||
"if(external.override) external.override(Object.assign({",
|
||||
Template.indent(
|
||||
this._overrides
|
||||
.map(([key, options]) => {
|
||||
const block = this.blocks[i++];
|
||||
const dep = block.dependencies[0];
|
||||
const module = moduleGraph.getModule(dep);
|
||||
return `${JSON.stringify(
|
||||
key
|
||||
)}: ${runtimeTemplate.basicFunction(
|
||||
"",
|
||||
`return ${runtimeTemplate.blockPromise({
|
||||
block,
|
||||
message: "",
|
||||
chunkGraph,
|
||||
runtimeRequirements
|
||||
})}.then(${runtimeTemplate.basicFunction(
|
||||
"",
|
||||
`return ${runtimeTemplate.returningFunction(
|
||||
runtimeTemplate.moduleRaw({
|
||||
module,
|
||||
chunkGraph,
|
||||
request: options.import,
|
||||
runtimeRequirements
|
||||
})
|
||||
)}`
|
||||
)})`
|
||||
)}`;
|
||||
})
|
||||
.join(",\n")
|
||||
),
|
||||
`}, ${RuntimeGlobals.overrides}));`,
|
||||
"return external;"
|
||||
]
|
||||
: [
|
||||
`if(external.override) external.override(${RuntimeGlobals.overrides});`,
|
||||
"return external;"
|
||||
]
|
||||
)};`
|
||||
]);
|
||||
const runtimeRequirements = new Set([RuntimeGlobals.initializeSharing]);
|
||||
const code = `register(${JSON.stringify(this._name)}, ${JSON.stringify(
|
||||
this._version || 0
|
||||
)}, ${
|
||||
this._eager
|
||||
? runtimeTemplate.syncModuleFactory({
|
||||
dependency: this.dependencies[0],
|
||||
chunkGraph,
|
||||
request: this._request,
|
||||
runtimeRequirements
|
||||
})
|
||||
: runtimeTemplate.asyncModuleFactory({
|
||||
block: this.blocks[0],
|
||||
chunkGraph,
|
||||
request: this._request,
|
||||
runtimeRequirements
|
||||
})
|
||||
});`;
|
||||
const sources = new Map();
|
||||
sources.set(
|
||||
"javascript",
|
||||
new OriginalSource(
|
||||
source,
|
||||
`webpack/remote-overrides ${this._overridesHash}`
|
||||
)
|
||||
);
|
||||
return { sources, runtimeRequirements };
|
||||
const data = new Map();
|
||||
data.set("share-init", [
|
||||
{
|
||||
shareScope: this._shareScope,
|
||||
initStage: 10,
|
||||
init: code
|
||||
}
|
||||
]);
|
||||
return { sources, data, runtimeRequirements };
|
||||
}
|
||||
|
||||
serialize(context) {
|
||||
const { write } = context;
|
||||
write(this._overrides);
|
||||
write(this._shareScope);
|
||||
write(this._name);
|
||||
write(this._version);
|
||||
write(this._request);
|
||||
write(this._eager);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
||||
static deserialize(context) {
|
||||
const { read } = context;
|
||||
const obj = new RemoteOverridesModule(read());
|
||||
const obj = new ProvideModule(read(), read(), read(), read(), read());
|
||||
obj.deserialize(context);
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
RemoteOverridesModule,
|
||||
"webpack/lib/container/RemoteOverridesModule"
|
||||
);
|
||||
makeSerializable(ProvideModule, "webpack/lib/sharing/ProvideModule");
|
||||
|
||||
module.exports = RemoteOverridesModule;
|
||||
module.exports = ProvideModule;
|
||||
|
|
@ -6,24 +6,30 @@
|
|||
"use strict";
|
||||
|
||||
const ModuleFactory = require("../ModuleFactory");
|
||||
const RemoteOverridesModule = require("./RemoteOverridesModule");
|
||||
const ProvideModule = require("./ProvideModule");
|
||||
|
||||
/** @typedef {import("../ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
|
||||
/** @typedef {import("../ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
|
||||
/** @typedef {import("./RemoteOverridesDependency")} RemoteOverridesDependency */
|
||||
/** @typedef {import("./ProvideDependency")} ProvideDependency */
|
||||
|
||||
class RemoteOverridesModuleFactory extends ModuleFactory {
|
||||
class ProvideModuleFactory extends ModuleFactory {
|
||||
/**
|
||||
* @param {ModuleFactoryCreateData} data data object
|
||||
* @param {function(Error=, ModuleFactoryResult=): void} callback callback
|
||||
* @returns {void}
|
||||
*/
|
||||
create(data, callback) {
|
||||
const dep = /** @type {RemoteOverridesDependency} */ (data.dependencies[0]);
|
||||
const dep = /** @type {ProvideDependency} */ (data.dependencies[0]);
|
||||
callback(null, {
|
||||
module: new RemoteOverridesModule(dep.overrides)
|
||||
module: new ProvideModule(
|
||||
dep.shareScope,
|
||||
dep.name,
|
||||
dep.version,
|
||||
dep.request,
|
||||
dep.eager
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RemoteOverridesModuleFactory;
|
||||
module.exports = ProvideModuleFactory;
|
||||
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const validateOptions = require("schema-utils");
|
||||
const schema = require("../../schemas/plugins/sharing/ProvideSharedPlugin.json");
|
||||
const WebpackError = require("../WebpackError");
|
||||
const { parseOptions } = require("../container/options");
|
||||
const LazySet = require("../util/LazySet");
|
||||
const ProvideDependency = require("./ProvideDependency");
|
||||
const ProvideModuleFactory = require("./ProvideModuleFactory");
|
||||
const ProvidedDependency = require("./ProvidedDependency");
|
||||
const { parseVersion } = require("./utils");
|
||||
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
||||
/**
|
||||
* @typedef {Object} ProvideOptions
|
||||
* @property {string} import
|
||||
* @property {string} shareScope
|
||||
* @property {(string|number)[] | undefined | false} version
|
||||
* @property {boolean} eager
|
||||
*/
|
||||
|
||||
class ProvideSharedPlugin {
|
||||
/**
|
||||
* @param {ProvideSharedPluginOptions} options options
|
||||
*/
|
||||
constructor(options) {
|
||||
validateOptions(schema, options, { name: "Provide Shared Plugin" });
|
||||
|
||||
/** @type {[string, ProvideOptions][]} */
|
||||
this._provides = parseOptions(
|
||||
options.provides,
|
||||
item => {
|
||||
if (Array.isArray(item))
|
||||
throw new Error("Unexpected array of provides");
|
||||
/** @type {ProvideOptions} */
|
||||
const result = {
|
||||
import: item,
|
||||
version: undefined,
|
||||
shareScope: options.shareScope || "default",
|
||||
eager: false
|
||||
};
|
||||
return result;
|
||||
},
|
||||
item => ({
|
||||
import: item.import,
|
||||
version:
|
||||
typeof item.version === "string"
|
||||
? parseVersion(item.version)
|
||||
: item.version,
|
||||
shareScope: item.shareScope || options.shareScope || "default",
|
||||
eager: !!item.eager
|
||||
})
|
||||
);
|
||||
this._provides.sort(([a], [b]) => {
|
||||
if (a < b) return -1;
|
||||
if (b < a) return 1;
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
const { _provides: provides } = this;
|
||||
|
||||
for (const [name, config] of provides) {
|
||||
compiler.hooks.make.tapAsync(
|
||||
"ProvideSharedPlugin",
|
||||
(compilation, callback) => {
|
||||
let version = config.version;
|
||||
const addModule = () => {
|
||||
compilation.addInclude(
|
||||
compiler.context,
|
||||
new ProvideDependency(
|
||||
config.shareScope,
|
||||
name,
|
||||
version || false,
|
||||
config.import,
|
||||
config.eager
|
||||
),
|
||||
{
|
||||
name: undefined
|
||||
},
|
||||
err => callback(err)
|
||||
);
|
||||
};
|
||||
if (
|
||||
version !== undefined ||
|
||||
config.import.startsWith("./") ||
|
||||
config.import.startsWith("../")
|
||||
) {
|
||||
return addModule();
|
||||
}
|
||||
const resolveContext = {
|
||||
/** @type {LazySet<string>} */
|
||||
fileDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
contextDependencies: new LazySet(),
|
||||
/** @type {LazySet<string>} */
|
||||
missingDependencies: new LazySet()
|
||||
};
|
||||
const resolver = compiler.resolverFactory.get("normal");
|
||||
resolver.resolve(
|
||||
{},
|
||||
compiler.context,
|
||||
config.import,
|
||||
resolveContext,
|
||||
(err, result, additionalInfo) => {
|
||||
compilation.fileDependencies.addAll(
|
||||
resolveContext.fileDependencies
|
||||
);
|
||||
compilation.contextDependencies.addAll(
|
||||
resolveContext.contextDependencies
|
||||
);
|
||||
compilation.missingDependencies.addAll(
|
||||
resolveContext.missingDependencies
|
||||
);
|
||||
let details;
|
||||
if (err) {
|
||||
details = `Failed to resolve: ${err}.`;
|
||||
} else if (!result) {
|
||||
details = `Resolved to void.`;
|
||||
} else if (!additionalInfo) {
|
||||
details = `No additional info provided from resolver.`;
|
||||
} else {
|
||||
const info = /** @type {any} */ (additionalInfo);
|
||||
const descriptionFileData = info.descriptionFileData;
|
||||
if (!descriptionFileData) {
|
||||
details =
|
||||
"No description file (usually package.json) found. Add description file with name and version, or manually specify version in shared config.";
|
||||
} else if (!descriptionFileData.version) {
|
||||
details =
|
||||
"No version in description file (usually package.json). Add version to description file, or manually specify version in shared config.";
|
||||
} else if (
|
||||
descriptionFileData.name &&
|
||||
config.import !== descriptionFileData.name &&
|
||||
!config.import.startsWith(`${descriptionFileData.name}/`)
|
||||
) {
|
||||
details = `Invalid name in description file (usually package.json): ${descriptionFileData.name}. Check location of description file, update name in description file, add missing description file to the package, or manually specify version in shared config.`;
|
||||
} else {
|
||||
version = parseVersion(descriptionFileData.version);
|
||||
}
|
||||
}
|
||||
if (!version) {
|
||||
const error = new WebpackError(
|
||||
`No version specified and unable to automatically determine one. ${details}`
|
||||
);
|
||||
error.file = `shared module ${name} -> ${config.import}`;
|
||||
compilation.warnings.push(error);
|
||||
}
|
||||
addModule();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
compiler.hooks.compilation.tap(
|
||||
"ProvideSharedPlugin",
|
||||
(compilation, { normalModuleFactory }) => {
|
||||
compilation.dependencyFactories.set(
|
||||
ProvidedDependency,
|
||||
normalModuleFactory
|
||||
);
|
||||
|
||||
compilation.dependencyFactories.set(
|
||||
ProvideDependency,
|
||||
new ProvideModuleFactory()
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ProvideSharedPlugin;
|
||||
|
|
@ -8,9 +8,7 @@
|
|||
const ModuleDependency = require("../dependencies/ModuleDependency");
|
||||
const makeSerializable = require("../util/makeSerializable");
|
||||
|
||||
/** @typedef {import("./RemoteOverridesModule").OverrideOptions} OverrideOptions */
|
||||
|
||||
class RemoteOverrideDependency extends ModuleDependency {
|
||||
class ProvidedDependency extends ModuleDependency {
|
||||
/**
|
||||
*
|
||||
* @param {string} request request string
|
||||
|
|
@ -20,13 +18,10 @@ class RemoteOverrideDependency extends ModuleDependency {
|
|||
}
|
||||
|
||||
get type() {
|
||||
return "remote override";
|
||||
return "provided";
|
||||
}
|
||||
}
|
||||
|
||||
makeSerializable(
|
||||
RemoteOverrideDependency,
|
||||
"webpack/lib/container/RemoteOverrideDependency"
|
||||
);
|
||||
makeSerializable(ProvidedDependency, "webpack/lib/sharing/ProvidedDependency");
|
||||
|
||||
module.exports = RemoteOverrideDependency;
|
||||
module.exports = ProvidedDependency;
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra and Zackary Jackson @ScriptedAlchemy
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const { parseOptions } = require("../container/options");
|
||||
const ConsumeSharedPlugin = require("./ConsumeSharedPlugin");
|
||||
const ProvideSharedPlugin = require("./ProvideSharedPlugin");
|
||||
const { isRequiredVersion } = require("./utils");
|
||||
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumeSharedPluginOptions} ConsumeSharedPluginOptions */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ConsumeSharedPlugin").ConsumesConfig} ConsumesConfig */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvidesConfig} ProvidesConfig */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharePluginOptions} SharePluginOptions */
|
||||
/** @typedef {import("../../declarations/plugins/sharing/SharePlugin").SharedConfig} SharedConfig */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
|
||||
class SharePlugin {
|
||||
/**
|
||||
* @param {SharePluginOptions} options options
|
||||
*/
|
||||
constructor(options) {
|
||||
/** @type {[string, SharedConfig][]} */
|
||||
const sharedOptions = parseOptions(
|
||||
options.shared,
|
||||
(item, key) => {
|
||||
if (typeof item !== "string")
|
||||
throw new Error("Unexpected array in shared");
|
||||
/** @type {SharedConfig} */
|
||||
const config =
|
||||
item === key || !isRequiredVersion(item)
|
||||
? {
|
||||
import: item
|
||||
}
|
||||
: {
|
||||
import: key,
|
||||
requiredVersion: item
|
||||
};
|
||||
return config;
|
||||
},
|
||||
item => item
|
||||
);
|
||||
/** @type {Record<string, ConsumesConfig>[]} */
|
||||
const consumes = sharedOptions.map(([key, options]) => ({
|
||||
[key]: {
|
||||
import: options.import,
|
||||
shareKey: options.shareKey,
|
||||
requiredVersion: options.requiredVersion,
|
||||
strictVersion: options.strictVersion,
|
||||
singleton: options.singleton,
|
||||
eager: options.eager
|
||||
}
|
||||
}));
|
||||
/** @type {Record<string, ProvidesConfig>[]} */
|
||||
const provides = sharedOptions
|
||||
.filter(([, options]) => options.import !== false)
|
||||
.map(([key, options]) => ({
|
||||
[options.shareKey || key]: {
|
||||
import: options.import || key,
|
||||
version: options.version,
|
||||
eager: options.eager
|
||||
}
|
||||
}));
|
||||
this._shareScope = options.shareScope;
|
||||
this._consumes = consumes;
|
||||
this._provides = provides;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the plugin
|
||||
* @param {Compiler} compiler the compiler instance
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(compiler) {
|
||||
new ConsumeSharedPlugin({
|
||||
shareScope: this._shareScope,
|
||||
consumes: this._consumes
|
||||
}).apply(compiler);
|
||||
new ProvideSharedPlugin({
|
||||
shareScope: this._shareScope,
|
||||
provides: this._provides
|
||||
}).apply(compiler);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SharePlugin;
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const RuntimeGlobals = require("../RuntimeGlobals");
|
||||
const RuntimeModule = require("../RuntimeModule");
|
||||
const Template = require("../Template");
|
||||
|
||||
class ShareRuntimeModule extends RuntimeModule {
|
||||
constructor() {
|
||||
super("sharing");
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string} runtime code
|
||||
*/
|
||||
generate() {
|
||||
const {
|
||||
runtimeTemplate,
|
||||
chunkGraph,
|
||||
codeGenerationResults
|
||||
} = this.compilation;
|
||||
/** @type {Map<string, Map<number, Set<string>>>} */
|
||||
const initCodePerScope = new Map();
|
||||
for (const chunk of this.chunk.getAllReferencedChunks()) {
|
||||
const modules = chunkGraph.getChunkModulesIterableBySourceType(
|
||||
chunk,
|
||||
"share-init"
|
||||
);
|
||||
if (!modules) continue;
|
||||
for (const m of modules) {
|
||||
const codeGen = codeGenerationResults.get(m);
|
||||
if (!codeGen) continue;
|
||||
const data = codeGen.data && codeGen.data.get("share-init");
|
||||
if (!data) continue;
|
||||
for (const item of data) {
|
||||
const { shareScope, initStage, init } = item;
|
||||
let stages = initCodePerScope.get(shareScope);
|
||||
if (stages === undefined) {
|
||||
initCodePerScope.set(shareScope, (stages = new Map()));
|
||||
}
|
||||
let list = stages.get(initStage || 0);
|
||||
if (list === undefined) {
|
||||
stages.set(initStage || 0, (list = new Set()));
|
||||
}
|
||||
list.add(init);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Template.asString([
|
||||
`${RuntimeGlobals.shareScopeMap} = {};`,
|
||||
"var initPromises = {};",
|
||||
`${RuntimeGlobals.initializeSharing} = ${runtimeTemplate.basicFunction(
|
||||
"name",
|
||||
[
|
||||
"// only runs once",
|
||||
"if(initPromises[name]) return initPromises[name];",
|
||||
"// handling circular init calls",
|
||||
"initPromises[name] = 1;",
|
||||
"// creates a new share scope if needed",
|
||||
`if(!${RuntimeGlobals.hasOwnProperty}(${RuntimeGlobals.shareScopeMap}, name)) ${RuntimeGlobals.shareScopeMap}[name] = {};`,
|
||||
"// runs all init snippets from all modules reachable",
|
||||
`var scope = ${RuntimeGlobals.shareScopeMap}[name];`,
|
||||
`var warn = ${runtimeTemplate.returningFunction(
|
||||
'typeof console !== "undefined" && console.warn && console.warn(msg);',
|
||||
"msg"
|
||||
)};`,
|
||||
`var register = ${runtimeTemplate.basicFunction(
|
||||
"name, version, factory, currentName",
|
||||
[
|
||||
"version = version || [];",
|
||||
"currentName = name;",
|
||||
`var versionConflict = ${runtimeTemplate.returningFunction(
|
||||
'warn("Version conflict for shared modules: " + name + " " + (v && v.join(".")) + " <=> " + (version && version.join(".")));'
|
||||
)};`,
|
||||
`var registerCurrent = ${runtimeTemplate.basicFunction("", [
|
||||
"if(scope[currentName]) {",
|
||||
Template.indent([
|
||||
"var v = scope[currentName].version || [];",
|
||||
"for(var i = 0; i < version.length && i < v.length; i++) {",
|
||||
Template.indent([
|
||||
"if(v[i] != version[i]) { // loose equal is intentional to match string and number",
|
||||
Template.indent([
|
||||
'if(typeof v[i] === "string" || typeof version[i] === "string") return versionConflict();',
|
||||
"if(v[i] > version[i]) return;",
|
||||
"if(v[i] < version[i]) { i = -1; break; }"
|
||||
]),
|
||||
"}"
|
||||
]),
|
||||
"}",
|
||||
"if(i >= 0 && version.length <= v.length) return;",
|
||||
'if(scope[currentName].loaded) return warn("Ignoring providing of already used shared module: " + name);'
|
||||
]),
|
||||
"}",
|
||||
"scope[currentName] = { get: factory, version: version };"
|
||||
])};`,
|
||||
"registerCurrent();",
|
||||
`version.forEach(${runtimeTemplate.basicFunction("part", [
|
||||
'currentName += "`" + part;',
|
||||
"registerCurrent();"
|
||||
])});`
|
||||
]
|
||||
)};`,
|
||||
`var initExternal = ${runtimeTemplate.basicFunction("id", [
|
||||
`var handleError = ${runtimeTemplate.returningFunction(
|
||||
'warn("Initialization of sharing external failed: " + err)',
|
||||
"err"
|
||||
)};`,
|
||||
"try {",
|
||||
Template.indent([
|
||||
"var module = __webpack_require__(id);",
|
||||
"if(!module) return;",
|
||||
`var initFn = ${runtimeTemplate.returningFunction(
|
||||
`module && module.init && module.init(${RuntimeGlobals.shareScopeMap}[name])`,
|
||||
"module"
|
||||
)}`,
|
||||
"if(module.then) return promises.push(module.then(initFn, handleError));",
|
||||
"var initResult = initFn(module);",
|
||||
"if(initResult && initResult.then) return promises.push(initResult.catch(handleError));"
|
||||
]),
|
||||
"} catch(err) { handleError(err); }"
|
||||
])}`,
|
||||
"var promises = [];",
|
||||
"switch(name) {",
|
||||
...Array.from(initCodePerScope, ([name, stages]) =>
|
||||
Template.indent([
|
||||
`case ${JSON.stringify(name)}: {`,
|
||||
Template.indent(
|
||||
Array.from(stages)
|
||||
.sort(([a], [b]) => a - b)
|
||||
.map(([, initCode]) =>
|
||||
Template.asString(Array.from(initCode))
|
||||
)
|
||||
),
|
||||
"}",
|
||||
"break;"
|
||||
])
|
||||
),
|
||||
"}",
|
||||
`return promises.length && (initPromises[name] = Promise.all(promises).then(${runtimeTemplate.returningFunction(
|
||||
"initPromises[name] = 1"
|
||||
)}));`
|
||||
]
|
||||
)};`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ShareRuntimeModule;
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @param {string} version version as string
|
||||
* @returns {(number|string)[]} version as array
|
||||
*/
|
||||
exports.parseRequiredVersion = version => {
|
||||
let fuzzyStart = Infinity;
|
||||
if (version.startsWith(">=")) {
|
||||
fuzzyStart = 0;
|
||||
version = version.slice(2);
|
||||
} else if (version.startsWith("^")) {
|
||||
fuzzyStart = 1;
|
||||
version = version.slice(1);
|
||||
} else if (version.startsWith("~")) {
|
||||
fuzzyStart = 2;
|
||||
version = version.slice(1);
|
||||
}
|
||||
return version
|
||||
.split(".")
|
||||
.map((x, i) => (i >= fuzzyStart && `${+x}` === x ? +x : x));
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} version version as string
|
||||
* @returns {(number|string)[]} version as array
|
||||
*/
|
||||
exports.parseVersion = version => {
|
||||
return version.split(".").map(x => (`${+x}` === x ? +x : x));
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {(number|string)[]} version version
|
||||
* @returns {string} version as string
|
||||
*/
|
||||
exports.versionToString = version => {
|
||||
if (!version) return "(unknown)";
|
||||
const info = version.map(value =>
|
||||
typeof value !== "string"
|
||||
? {
|
||||
type: "min",
|
||||
value: `${value}`
|
||||
}
|
||||
: `${+value}` === value
|
||||
? {
|
||||
type: "exact",
|
||||
value
|
||||
}
|
||||
: {
|
||||
type: "tag",
|
||||
value
|
||||
}
|
||||
);
|
||||
switch (`${info[0].type}.${info.length > 1 ? info[1].type : "undefined"}`) {
|
||||
case "exact.min":
|
||||
case "tag.min":
|
||||
if (!info.slice(2).some(i => i.type === "exact"))
|
||||
return `^${version.join(".")}`;
|
||||
break;
|
||||
|
||||
case "exact.exact":
|
||||
case "exact.tag":
|
||||
case "tag.exact":
|
||||
case "tag.tag":
|
||||
if (!info.slice(2).some(i => i.type === "exact"))
|
||||
return `~${version.join(".")}`;
|
||||
else if (!info.slice(2).some(i => i.type === "min"))
|
||||
return version.join(".");
|
||||
break;
|
||||
|
||||
case "min.min":
|
||||
case "min.tag":
|
||||
if (!info.slice(2).some(i => i.type === "exact"))
|
||||
return `>=${version.join(".")}`;
|
||||
break;
|
||||
|
||||
case "min.undefined":
|
||||
return `>=${version.join(".")}`;
|
||||
|
||||
case "exact.undefined":
|
||||
case "tag.undefined":
|
||||
return version.join(".");
|
||||
}
|
||||
return info
|
||||
.map(i => (i.type === "exact" ? i.value : `[>=${i.value}]`))
|
||||
.join(".");
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} str maybe required version
|
||||
* @returns {boolean} true, if it looks like a version
|
||||
*/
|
||||
exports.isRequiredVersion = str => {
|
||||
if (str.startsWith("^")) return true;
|
||||
if (str.startsWith("~")) return true;
|
||||
if (str.startsWith(">=")) return true;
|
||||
return /^\d/.test(str);
|
||||
};
|
||||
|
|
@ -23,17 +23,12 @@ module.exports = {
|
|||
require("../container/ContainerEntryModule"),
|
||||
"container/ContainerExposedDependency": () =>
|
||||
require("../container/ContainerExposedDependency"),
|
||||
"container/OverridableModule": () =>
|
||||
require("../container/OverridableModule"),
|
||||
"container/OverridableOriginalDependency": () =>
|
||||
require("../container/OverridableOriginalDependency"),
|
||||
"container/FallbackDependency": () =>
|
||||
require("../container/FallbackDependency"),
|
||||
"container/FallbackItemDependency": () =>
|
||||
require("../container/FallbackItemDependency"),
|
||||
"container/FallbackModule": () => require("../container/FallbackModule"),
|
||||
"container/RemoteModule": () => require("../container/RemoteModule"),
|
||||
"container/RemoteOverrideDependency": () =>
|
||||
require("../container/RemoteOverrideDependency"),
|
||||
"container/RemoteOverridesDependency": () =>
|
||||
require("../container/RemoteOverridesDependency"),
|
||||
"container/RemoteOverridesModule": () =>
|
||||
require("../container/RemoteOverridesModule"),
|
||||
"container/RemoteToExternalDependency": () =>
|
||||
require("../container/RemoteToExternalDependency"),
|
||||
"dependencies/AMDDefineDependency": () =>
|
||||
|
|
@ -159,6 +154,13 @@ module.exports = {
|
|||
ModuleWarning: () => require("../ModuleWarning"),
|
||||
NormalModule: () => require("../NormalModule"),
|
||||
RawModule: () => require("../RawModule"),
|
||||
"sharing/ConsumeSharedModule": () =>
|
||||
require("../sharing/ConsumeSharedModule"),
|
||||
"sharing/ConsumeFallbackDependency": () =>
|
||||
require("../sharing/ConsumeFallbackDependency"),
|
||||
"sharing/ProvideModule": () => require("../sharing/ProvideModule"),
|
||||
"sharing/ProvideDependency": () => require("../sharing/ProvideDependency"),
|
||||
"sharing/ProvidedDependency": () => require("../sharing/ProvidedDependency"),
|
||||
UnsupportedFeatureWarning: () => require("../UnsupportedFeatureWarning"),
|
||||
"util/LazySet": () => require("../util/LazySet"),
|
||||
WebpackError: () => require("../WebpackError"),
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "0.0.42",
|
||||
"@webassemblyjs/ast": "1.9.0",
|
||||
"@webassemblyjs/helper-module-context": "1.9.0",
|
||||
"@webassemblyjs/wasm-edit": "1.9.0",
|
||||
|
|
@ -23,13 +24,12 @@
|
|||
"pkg-dir": "^4.2.0",
|
||||
"schema-utils": "^2.5.0",
|
||||
"tapable": "2.0.0-beta.9",
|
||||
"terser-webpack-plugin": "^2.3.6",
|
||||
"terser-webpack-plugin": "^3.0.2",
|
||||
"watchpack": "2.0.0-beta.13",
|
||||
"webpack-sources": "2.0.0-beta.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.2",
|
||||
"@types/estree": "0.0.42",
|
||||
"@types/jest": "^25.1.5",
|
||||
"@types/node": "^12.6.9",
|
||||
"babel-loader": "^8.0.6",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,151 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Exposes": {
|
||||
"description": "Modules that should be exposed by this container. When provided, property name is used as public name, otherwise public name is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExposesConfig": {
|
||||
"description": "Advanced configuration for modules that should be exposed by this container.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Request to a module that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"ExposesItem": {
|
||||
"description": "Module that should be exposed by this container.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ExposesItems": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
}
|
||||
},
|
||||
"ExposesObject": {
|
||||
"description": "Modules that should be exposed by this container. Property names are used as public paths.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Remotes": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"RemotesConfig": {
|
||||
"description": "Advanced configuration for container locations from which modules should be resolved and loaded at runtime.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"external": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "The name of the share scope shared with this remote.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["external"]
|
||||
},
|
||||
"RemotesItem": {
|
||||
"description": "Container location from which modules should be resolved and loaded at runtime.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"RemotesItems": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
}
|
||||
},
|
||||
"RemotesObject": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,323 +0,0 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Exposes": {
|
||||
"description": "Modules that should be exposed by this container. When provided, property name is used as public name, otherwise public name is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ExposesConfig": {
|
||||
"description": "Advanced configuration for modules that should be exposed by this container.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Request to a module that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"ExposesItem": {
|
||||
"description": "Module that should be exposed by this container.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ExposesItems": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
}
|
||||
},
|
||||
"ExposesObject": {
|
||||
"description": "Modules that should be exposed by this container. Property names are used as public paths.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be exposed by this container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ExposesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ExposesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Overridables": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridablesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should be able to be overridden by the host.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridablesItem": {
|
||||
"description": "Request to a module in this container that should be able to be overridden by the host.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridablesItems": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
}
|
||||
},
|
||||
"OverridablesObject": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Overrides": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should override overridable modules in the remote container.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridesItem": {
|
||||
"description": "Request to a module in this container that should override overridable modules in the remote container.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridesObject": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Remotes": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"RemotesConfig": {
|
||||
"description": "Advanced configuration for container locations from which modules should be resolved and loaded at runtime.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"external": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["external"]
|
||||
},
|
||||
"RemotesItem": {
|
||||
"description": "Container location from which modules should be resolved and loaded at runtime.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"RemotesItems": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
}
|
||||
},
|
||||
"RemotesObject": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime. Property names are used as request scopes.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Container locations from which modules should be resolved and loaded at runtime.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/RemotesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Shared": {
|
||||
"description": "Modules that should be shared with remotes and/or host. When provided, property name is used as shared key, otherwise shared key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be shared with remotes and/or host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SharedConfig": {
|
||||
"description": "Advanced configuration for modules that should be shared with remotes and/or host.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"SharedItem": {
|
||||
"description": "Module that should be shared with remotes and/or host.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"SharedObject": {
|
||||
"description": "Modules that should be shared with remotes and/or host. Property names are used as shared keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be shared with remotes and/or host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Shared": {
|
||||
"description": "Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SharedConfig": {
|
||||
"description": "Advanced configuration for modules that should be shared in the share scope.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"eager": {
|
||||
"description": "Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"import": {
|
||||
"description": "Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "No provided or fallback module.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"requiredVersion": {
|
||||
"description": "Version requirement from module in share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version as string. Can be prefixed with '^' or '~' for minimum matches. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareKey": {
|
||||
"description": "Module is looked up under this key from the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"singleton": {
|
||||
"description": "Allow only a single version of the shared module in share scope (disabled by default).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"strictVersion": {
|
||||
"description": "Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of the provided module. Will replace lower matching versions, but not higher.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Don't provide a version.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"description": "Version as string. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"SharedItem": {
|
||||
"description": "A module that should be shared in the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"SharedObject": {
|
||||
"description": "Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"SharedVersionArray": {
|
||||
"description": "Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item of the version.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version number. It's assumed that the module is compatible with any higher version number.",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "Version tag. The module is only compatible with the exact matching version tag.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -221,77 +221,6 @@
|
|||
"system"
|
||||
]
|
||||
},
|
||||
"Overridables": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridablesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should be able to be overridden by the host.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridablesItem": {
|
||||
"description": "Request to a module in this container that should be able to be overridden by the host.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridablesItems": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
}
|
||||
},
|
||||
"OverridablesObject": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"UmdNamedDefine": {
|
||||
"description": "If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module.",
|
||||
"type": "boolean"
|
||||
|
|
@ -307,17 +236,21 @@
|
|||
"filename": {
|
||||
"description": "The filename for this container relative path inside the `output.path` directory.",
|
||||
"type": "string",
|
||||
"absolutePath": false
|
||||
"absolutePath": false,
|
||||
"minLength": 1
|
||||
},
|
||||
"library": {
|
||||
"$ref": "#/definitions/LibraryOptions"
|
||||
},
|
||||
"name": {
|
||||
"description": "The name for this container.",
|
||||
"type": "string"
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"overridables": {
|
||||
"$ref": "#/definitions/Overridables"
|
||||
"shareScope": {
|
||||
"description": "The name of the share scope which is shared with the host (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["name", "exposes"]
|
||||
|
|
|
|||
|
|
@ -23,59 +23,6 @@
|
|||
"import"
|
||||
]
|
||||
},
|
||||
"Overrides": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should override overridable modules in the remote container.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridesItem": {
|
||||
"description": "Request to a module in this container that should override overridable modules in the remote container.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridesObject": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Remotes": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.",
|
||||
"anyOf": [
|
||||
|
|
@ -113,6 +60,11 @@
|
|||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "The name of the share scope shared with this remote.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["external"]
|
||||
|
|
@ -152,9 +104,6 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"overrides": {
|
||||
"$ref": "#/definitions/Overrides"
|
||||
},
|
||||
"remoteType": {
|
||||
"description": "The external type of the remote containers.",
|
||||
"oneOf": [
|
||||
|
|
@ -165,6 +114,11 @@
|
|||
},
|
||||
"remotes": {
|
||||
"$ref": "#/definitions/Remotes"
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "The name of the share scope shared with all remotes (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["remoteType", "remotes"]
|
||||
|
|
|
|||
|
|
@ -244,130 +244,6 @@
|
|||
"system"
|
||||
]
|
||||
},
|
||||
"Overridables": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridablesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should be able to be overridden by the host.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridablesItem": {
|
||||
"description": "Request to a module in this container that should be able to be overridden by the host.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridablesItems": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
}
|
||||
},
|
||||
"OverridablesObject": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Overrides": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should override overridable modules in the remote container.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridesItem": {
|
||||
"description": "Request to a module in this container that should override overridable modules in the remote container.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridesObject": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should override overridable modules in the remote container.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridesItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"Remotes": {
|
||||
"description": "Container locations and request scopes from which modules should be resolved and loaded at runtime. When provided, property name is used as request scope, otherwise request scope is automatically inferred from container location.",
|
||||
"anyOf": [
|
||||
|
|
@ -405,6 +281,11 @@
|
|||
"$ref": "#/definitions/RemotesItems"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "The name of the share scope shared with this remote.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["external"]
|
||||
|
|
@ -440,12 +321,12 @@
|
|||
}
|
||||
},
|
||||
"Shared": {
|
||||
"description": "Modules that should be shared with remotes and/or host. When provided, property name is used as shared key, otherwise shared key is automatically inferred from request.",
|
||||
"description": "Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be shared with remotes and/or host.",
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
|
|
@ -462,26 +343,84 @@
|
|||
]
|
||||
},
|
||||
"SharedConfig": {
|
||||
"description": "Advanced configuration for modules that should be shared with remotes and/or host.",
|
||||
"description": "Advanced configuration for modules that should be shared in the share scope.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"eager": {
|
||||
"description": "Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"import": {
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
"description": "Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "No provided or fallback module.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"requiredVersion": {
|
||||
"description": "Version requirement from module in share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version as string. Can be prefixed with '^' or '~' for minimum matches. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareKey": {
|
||||
"description": "Module is looked up under this key from the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"singleton": {
|
||||
"description": "Allow only a single version of the shared module in share scope (disabled by default).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"strictVersion": {
|
||||
"description": "Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of the provided module. Will replace lower matching versions, but not higher.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Don't provide a version.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"description": "Version as string. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
}
|
||||
},
|
||||
"SharedItem": {
|
||||
"description": "Module that should be shared with remotes and/or host.",
|
||||
"description": "A module that should be shared in the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"SharedObject": {
|
||||
"description": "Modules that should be shared with remotes and/or host. Property names are used as shared keys.",
|
||||
"description": "Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be shared with remotes and/or host.",
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedConfig"
|
||||
|
|
@ -492,6 +431,23 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
"SharedVersionArray": {
|
||||
"description": "Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item of the version.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version number. It's assumed that the module is compatible with any higher version number.",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "Version tag. The module is only compatible with the exact matching version tag.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"UmdNamedDefine": {
|
||||
"description": "If `output.libraryTarget` is set to umd and `output.library` is set, setting this to true will name the AMD module.",
|
||||
"type": "boolean"
|
||||
|
|
@ -516,12 +472,6 @@
|
|||
"description": "The name of the container.",
|
||||
"type": "string"
|
||||
},
|
||||
"overridables": {
|
||||
"$ref": "#/definitions/Overridables"
|
||||
},
|
||||
"overrides": {
|
||||
"$ref": "#/definitions/Overrides"
|
||||
},
|
||||
"remoteType": {
|
||||
"description": "The external type of the remote containers.",
|
||||
"oneOf": [
|
||||
|
|
@ -533,6 +483,11 @@
|
|||
"remotes": {
|
||||
"$ref": "#/definitions/Remotes"
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name used for all shared modules (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shared": {
|
||||
"$ref": "#/definitions/Shared"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,84 +0,0 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Overridables": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"OverridablesConfig": {
|
||||
"description": "Advanced configuration for modules in this container that should be able to be overridden by the host.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"import": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"OverridablesItem": {
|
||||
"description": "Request to a module in this container that should be able to be overridden by the host.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"OverridablesItems": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
}
|
||||
},
|
||||
"OverridablesObject": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host. Property names are used as override keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Requests to modules in this container that should be able to be overridden by the host.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/OverridablesItems"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "OverridablesPluginOptions",
|
||||
"description": "Modules that should be able to be overridden. When provided, property name is used as override key, otherwise override key is automatically inferred from request.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"overridables": {
|
||||
"$ref": "#/definitions/Overridables"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Consumes": {
|
||||
"description": "Modules that should be consumed from share scope. When provided, property names are used to match requested modules in this compilation.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be consumed from share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ConsumesConfig": {
|
||||
"description": "Advanced configuration for modules that should be consumed from share scope.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"eager": {
|
||||
"description": "Include the fallback module directly instead behind an async request. This allows to use fallback module in initial load too. All possible shared modules need to be eager too.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"import": {
|
||||
"description": "Fallback module if no shared module is found in share scope. Defaults to the property name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "No fallback module.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesItem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"requiredVersion": {
|
||||
"description": "Version requirement from module in share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version as string. Can be prefixed with '^' or '~' for minimum matches. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareKey": {
|
||||
"description": "Module is looked up under this key from the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"singleton": {
|
||||
"description": "Allow only a single version of the shared module in share scope (disabled by default).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"strictVersion": {
|
||||
"description": "Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).",
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConsumesItem": {
|
||||
"description": "A module that should be consumed from share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ConsumesObject": {
|
||||
"description": "Modules that should be consumed from share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be consumed from share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ConsumesItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"SharedVersionArray": {
|
||||
"description": "Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item of the version.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version number. It's assumed that the module is compatible with any higher version number.",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "Version tag. The module is only compatible with the exact matching version tag.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "ConsumeSharedPluginOptions",
|
||||
"description": "Options for consuming shared modules.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"consumes": {
|
||||
"$ref": "#/definitions/Consumes"
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name used for all consumed modules (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["consumes"]
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Provides": {
|
||||
"description": "Modules that should be provided as shared modules to the share scope. When provided, property name is used as share key, otherwise share key is automatically inferred from request.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be provided as shared modules to the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ProvidesItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ProvidesObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ProvidesObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProvidesConfig": {
|
||||
"description": "Advanced configuration for modules that should be provided as shared modules to the share scope.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"eager": {
|
||||
"description": "Include the provided module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"import": {
|
||||
"$ref": "#/definitions/ProvidesItem"
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of the provided module. Will replace lower matching versions, but not higher.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Don't provide a version.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"description": "Version as string. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"required": ["import"]
|
||||
},
|
||||
"ProvidesItem": {
|
||||
"description": "Request to a module that should be provided as shared module to the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"ProvidesObject": {
|
||||
"description": "Modules that should be provided as shared modules to the share scope. Property names are used as share keys.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be provided as shared modules to the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ProvidesConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/ProvidesItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"SharedVersionArray": {
|
||||
"description": "Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item of the version.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version number. It's assumed that the module is compatible with any higher version number.",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "Version tag. The module is only compatible with the exact matching version tag.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "ProvideSharedPluginOptions",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"provides": {
|
||||
"$ref": "#/definitions/Provides"
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name used for all provided modules (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"required": ["provides"]
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
{
|
||||
"definitions": {
|
||||
"Shared": {
|
||||
"description": "Modules that should be shared in the share scope. When provided, property names are used to match requested modules in this compilation.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedObject"
|
||||
}
|
||||
]
|
||||
},
|
||||
"SharedConfig": {
|
||||
"description": "Advanced configuration for modules that should be shared in the share scope.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"eager": {
|
||||
"description": "Include the provided and fallback module directly instead behind an async request. This allows to use this shared module in initial load too. All possible shared modules need to be eager too.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"import": {
|
||||
"description": "Provided module that should be provided to share scope. Also acts as fallback module if no shared module is found in share scope or version isn't valid. Defaults to the property name.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "No provided or fallback module.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
},
|
||||
"requiredVersion": {
|
||||
"description": "Version requirement from module in share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version as string. Can be prefixed with '^' or '~' for minimum matches. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shareKey": {
|
||||
"description": "Module is looked up under this key from the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shareScope": {
|
||||
"description": "Share scope name.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"singleton": {
|
||||
"description": "Allow only a single version of the shared module in share scope (disabled by default).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"strictVersion": {
|
||||
"description": "Do not accept shared module if version is not valid (defaults to yes, if local fallback module is available and shared module is not a singleton, otherwise no, has no effect if there is no required version specified).",
|
||||
"type": "boolean"
|
||||
},
|
||||
"version": {
|
||||
"description": "Version of the provided module. Will replace lower matching versions, but not higher.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Don't provide a version.",
|
||||
"enum": [false]
|
||||
},
|
||||
{
|
||||
"description": "Version as string. Each part of the version should be separated by a dot '.'.",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedVersionArray"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"SharedItem": {
|
||||
"description": "A module that should be shared in the share scope.",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"SharedObject": {
|
||||
"description": "Modules that should be shared in the share scope. Property names are used to match requested modules in this compilation. Relative requests are resolved, module requests are matched unresolved, absolute paths will match resolved requests. A trailing slash will match all requests with this prefix. In this case shareKey must also have a trailing slash.",
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"description": "Modules that should be shared in the share scope.",
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/SharedConfig"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SharedItem"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"SharedVersionArray": {
|
||||
"description": "Version number as array. Numbers and strings are accepted. Strings are treated as tags, which only match exactly. Numbers can match higher numbers.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"description": "An item of the version.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Version number. It's assumed that the module is compatible with any higher version number.",
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"description": "Version tag. The module is only compatible with the exact matching version tag.",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "SharePluginOptions",
|
||||
"description": "Options for shared modules.",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"shareScope": {
|
||||
"description": "Share scope name used for all shared modules (defaults to 'default').",
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"shared": {
|
||||
"$ref": "#/definitions/Shared"
|
||||
}
|
||||
},
|
||||
"required": ["shared"]
|
||||
}
|
||||
|
|
@ -54,6 +54,8 @@ describe("Persistent Caching", () => {
|
|||
return new Promise((resolve, reject) => {
|
||||
webpack({ ...config, ...configAdditions }, (err, stats) => {
|
||||
if (err) return reject(err);
|
||||
if (stats.hasErrors())
|
||||
return reject(stats.toString({ preset: "errors-only" }));
|
||||
resolve(stats);
|
||||
});
|
||||
});
|
||||
|
|
@ -138,7 +140,8 @@ export default ${files.map((_, i) => `f${i}`).join(" + ")};
|
|||
const data = {
|
||||
"index.js":
|
||||
"export default import('container/src/exposed').then(m => m.default);",
|
||||
"exposed.js": "export default 42;"
|
||||
"exposed.js": "import lib from 'lib'; export default 21 + lib;",
|
||||
"lib.js": "export default 21"
|
||||
};
|
||||
await updateSrc(data);
|
||||
const configAdditions = {
|
||||
|
|
@ -148,7 +151,15 @@ export default ${files.map((_, i) => `f${i}`).join(" + ")};
|
|||
library: { type: "commonjs-module" },
|
||||
exposes: ["./src/exposed"],
|
||||
remotes: {
|
||||
container: "./container"
|
||||
container: ["./no-container", "./container"]
|
||||
},
|
||||
shared: {
|
||||
lib: {
|
||||
import: "./src/lib",
|
||||
shareKey: "lib",
|
||||
version: "1.2.3",
|
||||
requiredVersion: "^1.0.0"
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
|
|
|
|||
|
|
@ -835,9 +835,9 @@ external \\"test\\" 42 bytes [built]"
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for filter-warnings 1`] = `
|
||||
"Hash: 7763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca17763b48a6d4533935ca1
|
||||
"Hash: 73a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd6573a3198368d23afbbd65
|
||||
Child undefined:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -867,49 +867,49 @@ Child undefined:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child Terser:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle1.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle1.js
|
||||
Child /Terser/:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle2.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle2.js
|
||||
Child warnings => true:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle3.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle3.js
|
||||
Child [Terser]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle4.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle4.js
|
||||
Child [/Terser/]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle5.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle5.js
|
||||
Child [warnings => true]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
bundle6.js 556 bytes [emitted] [name: main]
|
||||
Entrypoint main = bundle6.js
|
||||
Child should not filter:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -939,7 +939,7 @@ Child should not filter:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child /should not filter/:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -969,7 +969,7 @@ Child /should not filter/:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child warnings => false:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -999,7 +999,7 @@ Child warnings => false:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child [should not filter]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -1029,7 +1029,7 @@ Child [should not filter]:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child [/should not filter/]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -1059,7 +1059,7 @@ Child [/should not filter/]:
|
|||
WARNING in Terser Plugin: Dropping unused function someUnUsedFunction5 [webpack://./index.js:12,0]
|
||||
|
||||
Child [warnings => false]:
|
||||
Hash: 7763b48a6d4533935ca1
|
||||
Hash: 73a3198368d23afbbd65
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -2731,9 +2731,9 @@ Entrypoint main = main.js
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for side-effects-optimization 1`] = `
|
||||
"Hash: d0117c2c1b2089facc60a79894f4120790dbe077
|
||||
"Hash: d7d1b4f45cd90d4abdb64369e7ea517dce8ffb09
|
||||
Child
|
||||
Hash: d0117c2c1b2089facc60
|
||||
Hash: d7d1b4f45cd90d4abdb6
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -2755,7 +2755,7 @@ Child
|
|||
ModuleConcatenation bailout: Module is not an ECMAScript module
|
||||
+ 2 hidden modules
|
||||
Child
|
||||
Hash: a79894f4120790dbe077
|
||||
Hash: 4369e7ea517dce8ffb09
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
@ -3879,7 +3879,7 @@ require.include() is deprecated and will be removed soon.
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for warnings-terser 1`] = `
|
||||
"Hash: 07f3df8603085e838fb0
|
||||
"Hash: 9d4799d2d13af78e55f1
|
||||
Time: X ms
|
||||
Built at: 1970-04-20 12:42:42
|
||||
Asset Size
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
module.exports = [{ code: /DEP_WEBPACK_COMPILATION_OPTIMIZE_CHUNK_ASSETS/ }];
|
||||
|
|
@ -17,7 +17,7 @@ module.exports = {
|
|||
external: "./container.js"
|
||||
}
|
||||
},
|
||||
shared: ["react"]
|
||||
shared: { react: { version: false } }
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,10 @@ module.exports = {
|
|||
"container-with-shared": "./container-with-shared.js"
|
||||
},
|
||||
shared: {
|
||||
shared: "./shared"
|
||||
"./shared": {
|
||||
shareKey: "shared",
|
||||
version: "1"
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
|
|
|
|||
3
test/configCases/container/1-container-full/node_modules/package.json
generated
vendored
Normal file
3
test/configCases/container/1-container-full/node_modules/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"version": "2.1.0"
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
import OldReact from "old-react";
|
||||
import OldReactSingleton from "old-react-singleton";
|
||||
import React from "react";
|
||||
import ComponentC from "containerB/ComponentC";
|
||||
|
||||
export default () => {
|
||||
return `App rendered with [${React()}] and [${ComponentC()}]`;
|
||||
return `App rendered with [${React()}] and [${OldReact()}] and [${OldReactSingleton()}] and [${ComponentC()}]`;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +0,0 @@
|
|||
import React from "react";
|
||||
|
||||
export default () => {
|
||||
return `ComponentB rendered with [${React()}]`;
|
||||
};
|
||||
|
|
@ -1,14 +1,46 @@
|
|||
let warnings = [];
|
||||
let oldWarn;
|
||||
|
||||
beforeEach(done => {
|
||||
oldWarn = console.warn;
|
||||
console.warn = m => warnings.push(m);
|
||||
done();
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
expectWarning();
|
||||
console.warn = oldWarn;
|
||||
done();
|
||||
});
|
||||
|
||||
const expectWarning = regexp => {
|
||||
if (!regexp) {
|
||||
expect(warnings).toEqual([]);
|
||||
} else {
|
||||
expect(warnings).toEqual(
|
||||
expect.objectContaining({
|
||||
0: expect.stringMatching(regexp),
|
||||
length: 1
|
||||
})
|
||||
);
|
||||
}
|
||||
warnings.length = 0;
|
||||
};
|
||||
|
||||
it("should load the component from container", () => {
|
||||
return import("./App").then(({ default: App }) => {
|
||||
expectWarning(
|
||||
/Unsatisfied version of shared singleton module react@8 \(required react@2\)/
|
||||
);
|
||||
const rendered = App();
|
||||
expect(rendered).toBe(
|
||||
"App rendered with [This is react 8] and [ComponentC rendered with [This is react 8] and [ComponentA rendered with [This is react 8]] and [ComponentB rendered with [This is react 8]]]"
|
||||
"App rendered with [This is react 8] and [This is react 2.1.0] and [This is react 8] and [ComponentC rendered with [This is react 8] and [ComponentA rendered with [This is react 8]] and [ComponentB rendered with [This is react 8]]]"
|
||||
);
|
||||
return import("./upgrade-react").then(({ default: upgrade }) => {
|
||||
upgrade();
|
||||
const rendered = App();
|
||||
expect(rendered).toBe(
|
||||
"App rendered with [This is react 9] and [ComponentC rendered with [This is react 9] and [ComponentA rendered with [This is react 9]] and [ComponentB rendered with [This is react 9]]]"
|
||||
"App rendered with [This is react 9] and [This is react 2.1.0] and [This is react 9] and [ComponentC rendered with [This is react 9] and [ComponentA rendered with [This is react 9]] and [ComponentB rendered with [This is react 9]]]"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
3
test/configCases/container/2-container-full/node_modules/package.json
generated
vendored
Normal file
3
test/configCases/container/2-container-full/node_modules/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"version": "8"
|
||||
}
|
||||
|
|
@ -16,7 +16,20 @@ module.exports = {
|
|||
]
|
||||
},
|
||||
exposes: ["./Self"],
|
||||
shared: ["react"]
|
||||
shared: {
|
||||
react: "react",
|
||||
"old-react": {
|
||||
import: false,
|
||||
shareKey: "react",
|
||||
requiredVersion: "^2"
|
||||
},
|
||||
"old-react-singleton": {
|
||||
import: false,
|
||||
shareKey: "react",
|
||||
requiredVersion: "^2",
|
||||
singleton: true
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ it("should have good module ids", async () => {
|
|||
"./b.js",
|
||||
"./modules.js",
|
||||
"webpack/container/entry/container-with-shared",
|
||||
"webpack/container/overridable/shared=./shared"
|
||||
"webpack/sharing/consume/default/shared/./shared"
|
||||
]);
|
||||
expect(m1).toEqual([
|
||||
"./a.js",
|
||||
|
|
@ -29,7 +29,6 @@ it("should have good module ids", async () => {
|
|||
"./modules.js",
|
||||
"webpack/container/entry/container-no-shared",
|
||||
"webpack/container/reference/container-with-shared",
|
||||
"webpack/container/remote-overrides/empty",
|
||||
"webpack/container/remote/container-with-shared/b",
|
||||
"webpack/container/remote/container-with-shared/modules"
|
||||
]);
|
||||
|
|
@ -37,7 +36,6 @@ it("should have good module ids", async () => {
|
|||
"./index.js",
|
||||
"./shared.js",
|
||||
"webpack/container/reference/container-no-shared",
|
||||
"webpack/container/remote-overrides/7d3b8a",
|
||||
"webpack/container/remote/container-no-shared/a",
|
||||
"webpack/container/remote/container-no-shared/b",
|
||||
"webpack/container/remote/container-no-shared/modules",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,10 @@ module.exports = {
|
|||
"../1-transitive-overriding/container-no-shared.js"
|
||||
},
|
||||
shared: {
|
||||
shared: "./shared"
|
||||
"./shared": {
|
||||
shareKey: "shared",
|
||||
version: "2"
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
import React from "react";
|
||||
import ComponentC from "containerB/ComponentC";
|
||||
|
||||
export default () => {
|
||||
return `App rendered with [${React()}] and [${ComponentC()}]`;
|
||||
};
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
it("should load the component from container", () => {
|
||||
return import("./App").then(({ default: App }) => {
|
||||
const rendered = App();
|
||||
expect(rendered).toBe(
|
||||
"App rendered with [This is react 2.1.0] and [ComponentC rendered with [This is react 2.1.0] and [ComponentA rendered with [This is react 2.1.0]] and [ComponentB rendered with [This is react 2.1.0]]]"
|
||||
);
|
||||
return import("./upgrade-react").then(({ default: upgrade }) => {
|
||||
upgrade();
|
||||
const rendered = App();
|
||||
expect(rendered).toBe(
|
||||
"App rendered with [This is react 9] and [ComponentC rendered with [This is react 9] and [ComponentA rendered with [This is react 9]] and [ComponentB rendered with [This is react 9]]]"
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let version = "8";
|
||||
export default () => `This is react ${version}`;
|
||||
export function setVersion(v) { version = v; }
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import { setVersion } from "react";
|
||||
|
||||
export default function upgrade() {
|
||||
setVersion("9");
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
module.exports = [
|
||||
[/No version specified and unable to automatically determine one/]
|
||||
];
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
const { ModuleFederationPlugin } = require("../../../../").container;
|
||||
|
||||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
plugins: [
|
||||
new ModuleFederationPlugin({
|
||||
remoteType: "commonjs-module",
|
||||
remotes: {
|
||||
containerB: "../1-container-full/container.js"
|
||||
},
|
||||
shared: {
|
||||
react: "^2.0.1"
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
@ -1,17 +1,19 @@
|
|||
it("should expose modules from the container", async () => {
|
||||
const container = __non_webpack_require__("./container-file.js");
|
||||
expect(container).toBeTypeOf("object");
|
||||
expect(container.override).toBeTypeOf("function");
|
||||
container.override({
|
||||
value: () =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(() => ({
|
||||
__esModule: true,
|
||||
default: "overriden-value"
|
||||
}));
|
||||
}, 100);
|
||||
})
|
||||
expect(container.init).toBeTypeOf("function");
|
||||
container.init({
|
||||
value: {
|
||||
get: () =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(() => ({
|
||||
__esModule: true,
|
||||
default: "overriden-value"
|
||||
}));
|
||||
}, 100);
|
||||
})
|
||||
}
|
||||
});
|
||||
const testFactory = await container.get("./test");
|
||||
expect(testFactory).toBeTypeOf("function");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const { ContainerPlugin } = require("../../../../").container;
|
||||
const { ConsumeSharedPlugin } = require("../../../../").sharing;
|
||||
|
||||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
|
|
@ -11,9 +12,13 @@ module.exports = {
|
|||
},
|
||||
exposes: {
|
||||
"./test": "./test"
|
||||
},
|
||||
overridables: {
|
||||
value: "./value"
|
||||
}
|
||||
}),
|
||||
new ConsumeSharedPlugin({
|
||||
consumes: {
|
||||
"./value": {
|
||||
shareKey: "value"
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
module.exports = {
|
||||
moduleScope(scope) {
|
||||
const o = {
|
||||
test: () => () => x => `wrong ${x}`
|
||||
};
|
||||
let ss;
|
||||
scope.ABC = {
|
||||
async get(module) {
|
||||
const testFactory = await o["test"]();
|
||||
const testFactory = await ss.test.get();
|
||||
const test = testFactory();
|
||||
return () => {
|
||||
return test(module);
|
||||
};
|
||||
},
|
||||
override(overrides) {
|
||||
Object.assign(o, overrides);
|
||||
async init(shareScope) {
|
||||
ss = shareScope;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const { ContainerReferencePlugin } = require("../../../../").container;
|
||||
const { ProvideSharedPlugin } = require("../../../../").sharing;
|
||||
|
||||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
|
|
@ -7,10 +8,13 @@ module.exports = {
|
|||
remoteType: "var",
|
||||
remotes: {
|
||||
abc: "ABC"
|
||||
},
|
||||
overrides: {
|
||||
}
|
||||
}),
|
||||
new ProvideSharedPlugin({
|
||||
provides: {
|
||||
test: {
|
||||
import: "./new-test"
|
||||
import: "./new-test",
|
||||
version: false
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,5 +1,34 @@
|
|||
"use strict";
|
||||
|
||||
let warnings = [];
|
||||
let oldWarn;
|
||||
|
||||
beforeEach(done => {
|
||||
oldWarn = console.warn;
|
||||
console.warn = m => warnings.push(m);
|
||||
done();
|
||||
});
|
||||
|
||||
afterEach(done => {
|
||||
expectWarning();
|
||||
console.warn = oldWarn;
|
||||
done();
|
||||
});
|
||||
|
||||
const expectWarning = regexp => {
|
||||
if (!regexp) {
|
||||
expect(warnings).toEqual([]);
|
||||
} else {
|
||||
expect(warnings).toEqual(
|
||||
expect.objectContaining({
|
||||
0: expect.stringMatching(regexp),
|
||||
length: 1
|
||||
})
|
||||
);
|
||||
}
|
||||
warnings.length = 0;
|
||||
};
|
||||
|
||||
it("should allow to handle remote loading error with import()", async () => {
|
||||
await expect(import("./loading-error")).rejects.toEqual(
|
||||
expect.objectContaining({
|
||||
|
|
@ -33,6 +62,8 @@ it("should allow to handle invalid remote module error with import()", async ()
|
|||
'Module "./invalid" does not exist in container.\nwhile loading "./invalid" from webpack/container/reference/remote'
|
||||
})
|
||||
);
|
||||
// at this point sharing initialization runs and triggers a warning that 'invalid' remote can't be loaded
|
||||
expectWarning(/ENOENT/);
|
||||
});
|
||||
|
||||
it("should allow to handle invalid remote module error with require", async () => {
|
||||
|
|
|
|||
4
test/configCases/container/exposed-overridables/node_modules/package.json
generated
vendored
Normal file
4
test/configCases/container/exposed-overridables/node_modules/package.json
generated
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "react",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
|
|
@ -9,7 +9,11 @@ module.exports = {
|
|||
exposes: {
|
||||
"./Button": "./Button"
|
||||
},
|
||||
shared: ["react"]
|
||||
shared: {
|
||||
react: {
|
||||
eager: true
|
||||
}
|
||||
}
|
||||
})
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
module.exports = "original1-cjs";
|
||||
|
|
@ -1 +0,0 @@
|
|||
module.exports = "original2-cjs";
|
||||
|
|
@ -1 +0,0 @@
|
|||
module.exports = "original3-cjs";
|
||||
|
|
@ -1,86 +0,0 @@
|
|||
__webpack_override__({
|
||||
test1: () =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(() => ({
|
||||
__esModule: true,
|
||||
default: "overriden1"
|
||||
}));
|
||||
}, 100);
|
||||
}),
|
||||
test3: () => () => "overriden3",
|
||||
package: () =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(() => "overriden-package");
|
||||
}, 100);
|
||||
}),
|
||||
"././options/test1": () => () => "1",
|
||||
"nested1/options/test2": () => () => "2",
|
||||
"nested2/deep/deep": () => () => "3"
|
||||
});
|
||||
|
||||
it("should be able to override a esm overridable", () => {
|
||||
return import("./modules/test1").then(m => {
|
||||
expect(m.default).toBe("overriden1");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to not override a esm overridable", () => {
|
||||
return import("./modules/test2").then(m => {
|
||||
expect(m.default).toBe("original2");
|
||||
});
|
||||
});
|
||||
|
||||
import test3 from "./modules/test3";
|
||||
it("should be able to use an overridable module in the initial chunk, but it's not overriden", () => {
|
||||
expect(test3).toBe("original3");
|
||||
});
|
||||
|
||||
it("should be able to override a cjs overridable", () => {
|
||||
return import("./cjs/test1").then(m => {
|
||||
expect(m.default).toBe("overriden1");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to not override a cjs overridable", () => {
|
||||
return import("./cjs/test2").then(m => {
|
||||
expect(m.default).toBe("original2-cjs");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to use an overridable module in the initial chunk, and it's overriden", () => {
|
||||
expect(require("./cjs/test3")).toBe("overriden3");
|
||||
});
|
||||
|
||||
it("should be able to override with a package name shortcut", () => {
|
||||
return import("package").then(m => {
|
||||
expect(m.default).toBe("overriden-package");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to override a relative request via shortcut", () => {
|
||||
return import("./options/test1").then(m => {
|
||||
expect(m.default).toBe("1");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to override a nested relative request via shortcut", () => {
|
||||
return import("./options/test2").then(m => {
|
||||
expect(m.default).toBe("2");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to override a deep nested request", () => {
|
||||
return import("./options/test3").then(m => {
|
||||
expect(m.default).toBe("3");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to override when fallback module has multiple chunks", () => {
|
||||
return import("./splitChunks").then(m => {
|
||||
expect(m.default).toBe(
|
||||
"index+app+vendor+shared+shared-separate+shared+shared-separate"
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default "original1";
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default "original2";
|
||||
|
|
@ -1 +0,0 @@
|
|||
export default "original3";
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue