webpack/lib/sharing/ProvideSharedPlugin.js

114 lines
2.8 KiB
JavaScript
Raw Normal View History

2020-05-23 22:08:51 +08:00
/*
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 { parseOptions } = require("../container/options");
const ProvideDependency = require("./ProvideDependency");
const ProvideModuleFactory = require("./ProvideModuleFactory");
const ProvidedDependency = require("./ProvidedDependency");
2020-05-25 23:14:59 +08:00
const { parseVersion } = require("./utils");
2020-05-23 22:08:51 +08:00
/** @typedef {import("../../declarations/plugins/sharing/ProvideSharedPlugin").ProvideSharedPluginOptions} ProvideSharedPluginOptions */
/** @typedef {import("../Compiler")} Compiler */
/**
* @typedef {Object} ProvideOptions
* @property {string} import
* @property {string} shareScope
* @property {(string|number)[]} version
* @property {boolean} eager
2020-05-23 22:08:51 +08:00
*/
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 overrides");
/** @type {ProvideOptions} */
const result = {
2020-05-23 22:08:51 +08:00
import: item,
version: undefined,
shareScope: options.shareScope || "default",
eager: false
2020-05-23 22:08:51 +08:00
};
return result;
2020-05-23 22:08:51 +08:00
},
item => ({
import: item.import,
version:
typeof item.version === "string"
2020-05-25 23:14:59 +08:00
? parseVersion(item.version)
2020-05-23 22:08:51 +08:00
: item.version,
shareScope: item.shareScope || options.shareScope || "default",
eager: !!item.eager
2020-05-23 22:08:51 +08:00
})
);
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) => {
compilation.addInclude(
compiler.context,
new ProvideDependency(
config.shareScope,
name,
config.version,
config.import,
config.eager
2020-05-23 22:08:51 +08:00
),
{
name: undefined
},
err => callback(err)
);
}
);
}
compiler.hooks.compilation.tap(
"ProvideSharedPlugin",
(compilation, { normalModuleFactory }) => {
compilation.dependencyFactories.set(
ProvidedDependency,
normalModuleFactory
);
compilation.dependencyFactories.set(
ProvideDependency,
new ProvideModuleFactory()
);
}
);
}
}
module.exports = ProvideSharedPlugin;