| | |
| | | |
| | | const WebpackError = require("../WebpackError"); |
| | | const { parseOptions } = require("../container/options"); |
| | | const createSchemaValidation = require("../util/create-schema-validation"); |
| | | const ProvideForSharedDependency = require("./ProvideForSharedDependency"); |
| | | const ProvideSharedDependency = require("./ProvideSharedDependency"); |
| | | const ProvideSharedModuleFactory = require("./ProvideSharedModuleFactory"); |
| | |
| | | /** @typedef {import("../Compiler")} Compiler */ |
| | | /** @typedef {import("../NormalModuleFactory").NormalModuleCreateData} NormalModuleCreateData */ |
| | | |
| | | const validate = createSchemaValidation( |
| | | require("../../schemas/plugins/sharing/ProvideSharedPlugin.check"), |
| | | () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"), |
| | | { |
| | | name: "Provide Shared Plugin", |
| | | baseDataPath: "options" |
| | | } |
| | | ); |
| | | |
| | | /** |
| | | * Defines the provide options type used by this module. |
| | | * @typedef {object} ProvideOptions |
| | | * @property {string} shareKey |
| | | * @property {string} shareScope |
| | |
| | | |
| | | class ProvideSharedPlugin { |
| | | /** |
| | | * Creates an instance of ProvideSharedPlugin. |
| | | * @param {ProvideSharedPluginOptions} options options |
| | | */ |
| | | constructor(options) { |
| | | validate(options); |
| | | |
| | | this._provides = /** @type {[string, ProvideOptions][]} */ ( |
| | | parseOptions( |
| | | options.provides, |
| | | (item) => { |
| | | if (Array.isArray(item)) { |
| | | throw new Error("Unexpected array of provides"); |
| | | } |
| | | /** @type {ProvideOptions} */ |
| | | const result = { |
| | | shareKey: item, |
| | | version: undefined, |
| | | shareScope: options.shareScope || "default", |
| | | eager: false |
| | | }; |
| | | return result; |
| | | }, |
| | | (item) => ({ |
| | | shareKey: item.shareKey, |
| | | version: item.version, |
| | | shareScope: item.shareScope || options.shareScope || "default", |
| | | eager: Boolean(item.eager) |
| | | }) |
| | | ) |
| | | ); |
| | | this._provides.sort(([a], [b]) => { |
| | | if (a < b) return -1; |
| | | if (b < a) return 1; |
| | | return 0; |
| | | }); |
| | | this.options = options; |
| | | } |
| | | |
| | | /** |
| | | * Apply the plugin |
| | | * Applies the plugin by registering its hooks on the compiler. |
| | | * @param {Compiler} compiler the compiler instance |
| | | * @returns {void} |
| | | */ |
| | | apply(compiler) { |
| | | compiler.hooks.validate.tap(PLUGIN_NAME, () => { |
| | | compiler.validate( |
| | | () => require("../../schemas/plugins/sharing/ProvideSharedPlugin.json"), |
| | | this.options, |
| | | { |
| | | name: "Provide Shared Plugin", |
| | | baseDataPath: "options" |
| | | }, |
| | | (options) => |
| | | require("../../schemas/plugins/sharing/ProvideSharedPlugin.check")( |
| | | options |
| | | ) |
| | | ); |
| | | }); |
| | | |
| | | /** @type {[string, ProvideOptions][]} */ |
| | | const provides = parseOptions( |
| | | this.options.provides, |
| | | (item) => { |
| | | if (Array.isArray(item)) { |
| | | throw new Error("Unexpected array of provides"); |
| | | } |
| | | /** @type {ProvideOptions} */ |
| | | const result = { |
| | | shareKey: item, |
| | | version: undefined, |
| | | shareScope: this.options.shareScope || "default", |
| | | eager: false |
| | | }; |
| | | return result; |
| | | }, |
| | | (item) => ({ |
| | | shareKey: /** @type {string} */ (item.shareKey), |
| | | version: item.version, |
| | | shareScope: item.shareScope || this.options.shareScope || "default", |
| | | eager: Boolean(item.eager) |
| | | }) |
| | | ).sort(([a], [b]) => { |
| | | if (a < b) return -1; |
| | | if (b < a) return 1; |
| | | return 0; |
| | | }); |
| | | |
| | | /** @type {WeakMap<Compilation, ResolvedProvideMap>} */ |
| | | const compilationData = new WeakMap(); |
| | | |
| | |
| | | const matchProvides = new Map(); |
| | | /** @type {Map<string, ProvideOptions>} */ |
| | | const prefixMatchProvides = new Map(); |
| | | for (const [request, config] of this._provides) { |
| | | if (/^(\/|[A-Za-z]:\\|\\\\|\.\.?(\/|$))/.test(request)) { |
| | | for (const [request, config] of provides) { |
| | | if (/^(?:\/|[A-Z]:\\|\\\\|\.\.?(?:\/|$))/i.test(request)) { |
| | | // relative request |
| | | resolvedProvideMap.set(request, { |
| | | config, |
| | | version: config.version |
| | | }); |
| | | } else if (/^(\/|[A-Za-z]:\\|\\\\)/.test(request)) { |
| | | } else if (/^(?:\/|[A-Z]:\\|\\\\)/i.test(request)) { |
| | | // absolute path |
| | | resolvedProvideMap.set(request, { |
| | | config, |
| | |
| | | } |
| | | compilationData.set(compilation, resolvedProvideMap); |
| | | /** |
| | | * Provide shared module. |
| | | * @param {string} key key |
| | | * @param {ProvideOptions} config config |
| | | * @param {NormalModuleCreateData["resource"]} resource resource |