summaryrefslogtreecommitdiff
path: root/node_modules/webpack/lib/NormalModuleFactory.js
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
committerlittleblack111 <littleblack11111@gmail.com>2023-11-05 17:16:09 +0800
commitd1d9f00b1bd660842addf5e6b1d1b64c852a9eea (patch)
tree60fb37ae73a1109d95301de5ec9b61b5726a4b61 /node_modules/webpack/lib/NormalModuleFactory.js
parent7c85166c4cbdd862fc4252007d2df5befcbc2a58 (diff)
added hover prefixer
Diffstat (limited to 'node_modules/webpack/lib/NormalModuleFactory.js')
-rw-r--r--node_modules/webpack/lib/NormalModuleFactory.js1166
1 files changed, 1166 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/NormalModuleFactory.js b/node_modules/webpack/lib/NormalModuleFactory.js
new file mode 100644
index 00000000..a0d8b767
--- /dev/null
+++ b/node_modules/webpack/lib/NormalModuleFactory.js
@@ -0,0 +1,1166 @@
+/*
+ MIT License http://www.opensource.org/licenses/mit-license.php
+ Author Tobias Koppers @sokra
+*/
+
+"use strict";
+
+const { getContext } = require("loader-runner");
+const asyncLib = require("neo-async");
+const {
+ AsyncSeriesBailHook,
+ SyncWaterfallHook,
+ SyncBailHook,
+ SyncHook,
+ HookMap
+} = require("tapable");
+const ChunkGraph = require("./ChunkGraph");
+const Module = require("./Module");
+const ModuleFactory = require("./ModuleFactory");
+const ModuleGraph = require("./ModuleGraph");
+const { JAVASCRIPT_MODULE_TYPE_AUTO } = require("./ModuleTypeConstants");
+const NormalModule = require("./NormalModule");
+const BasicEffectRulePlugin = require("./rules/BasicEffectRulePlugin");
+const BasicMatcherRulePlugin = require("./rules/BasicMatcherRulePlugin");
+const ObjectMatcherRulePlugin = require("./rules/ObjectMatcherRulePlugin");
+const RuleSetCompiler = require("./rules/RuleSetCompiler");
+const UseEffectRulePlugin = require("./rules/UseEffectRulePlugin");
+const LazySet = require("./util/LazySet");
+const { getScheme } = require("./util/URLAbsoluteSpecifier");
+const { cachedCleverMerge, cachedSetProperty } = require("./util/cleverMerge");
+const { join } = require("./util/fs");
+const {
+ parseResource,
+ parseResourceWithoutFragment
+} = require("./util/identifier");
+
+/** @typedef {import("../declarations/WebpackOptions").ModuleOptionsNormalized} ModuleOptions */
+/** @typedef {import("../declarations/WebpackOptions").RuleSetRule} RuleSetRule */
+/** @typedef {import("./Generator")} Generator */
+/** @typedef {import("./ModuleFactory").ModuleFactoryCreateData} ModuleFactoryCreateData */
+/** @typedef {import("./ModuleFactory").ModuleFactoryResult} ModuleFactoryResult */
+/** @typedef {import("./NormalModule").NormalModuleCreateData} NormalModuleCreateData */
+/** @typedef {import("./Parser")} Parser */
+/** @typedef {import("./ResolverFactory")} ResolverFactory */
+/** @typedef {import("./dependencies/ModuleDependency")} ModuleDependency */
+/** @typedef {import("./util/fs").InputFileSystem} InputFileSystem */
+
+/** @typedef {Pick<RuleSetRule, 'type'|'sideEffects'|'parser'|'generator'|'resolve'|'layer'>} ModuleSettings */
+/** @typedef {Partial<NormalModuleCreateData & {settings: ModuleSettings}>} CreateData */
+
+/**
+ * @typedef {Object} ResolveData
+ * @property {ModuleFactoryCreateData["contextInfo"]} contextInfo
+ * @property {ModuleFactoryCreateData["resolveOptions"]} resolveOptions
+ * @property {string} context
+ * @property {string} request
+ * @property {Record<string, any> | undefined} assertions
+ * @property {ModuleDependency[]} dependencies
+ * @property {string} dependencyType
+ * @property {CreateData} createData
+ * @property {LazySet<string>} fileDependencies
+ * @property {LazySet<string>} missingDependencies
+ * @property {LazySet<string>} contextDependencies
+ * @property {boolean} cacheable allow to use the unsafe cache
+ */
+
+/**
+ * @typedef {Object} ResourceData
+ * @property {string} resource
+ * @property {string} path
+ * @property {string} query
+ * @property {string} fragment
+ * @property {string=} context
+ */
+
+/** @typedef {ResourceData & { data: Record<string, any> }} ResourceDataWithData */
+
+/** @typedef {Object} ParsedLoaderRequest
+ * @property {string} loader loader
+ * @property {string|undefined} options options
+ */
+
+const EMPTY_RESOLVE_OPTIONS = {};
+const EMPTY_PARSER_OPTIONS = {};
+const EMPTY_GENERATOR_OPTIONS = {};
+const EMPTY_ELEMENTS = [];
+
+const MATCH_RESOURCE_REGEX = /^([^!]+)!=!/;
+const LEADING_DOT_EXTENSION_REGEX = /^[^.]/;
+
+const loaderToIdent = data => {
+ if (!data.options) {
+ return data.loader;
+ }
+ if (typeof data.options === "string") {
+ return data.loader + "?" + data.options;
+ }
+ if (typeof data.options !== "object") {
+ throw new Error("loader options must be string or object");
+ }
+ if (data.ident) {
+ return data.loader + "??" + data.ident;
+ }
+ return data.loader + "?" + JSON.stringify(data.options);
+};
+
+const stringifyLoadersAndResource = (loaders, resource) => {
+ let str = "";
+ for (const loader of loaders) {
+ str += loaderToIdent(loader) + "!";
+ }
+ return str + resource;
+};
+
+const needCalls = (times, callback) => {
+ return err => {
+ if (--times === 0) {
+ return callback(err);
+ }
+ if (err && times > 0) {
+ times = NaN;
+ return callback(err);
+ }
+ };
+};
+
+const mergeGlobalOptions = (globalOptions, type, localOptions) => {
+ const parts = type.split("/");
+ let result;
+ let current = "";
+ for (const part of parts) {
+ current = current ? `${current}/${part}` : part;
+ const options = globalOptions[current];
+ if (typeof options === "object") {
+ if (result === undefined) {
+ result = options;
+ } else {
+ result = cachedCleverMerge(result, options);
+ }
+ }
+ }
+ if (result === undefined) {
+ return localOptions;
+ } else {
+ return cachedCleverMerge(result, localOptions);
+ }
+};
+
+// TODO webpack 6 remove
+const deprecationChangedHookMessage = (name, hook) => {
+ const names = hook.taps
+ .map(tapped => {
+ return tapped.name;
+ })
+ .join(", ");
+
+ return (
+ `NormalModuleFactory.${name} (${names}) is no longer a waterfall hook, but a bailing hook instead. ` +
+ "Do not return the passed object, but modify it instead. " +
+ "Returning false will ignore the request and results in no module created."
+ );
+};
+
+const ruleSetCompiler = new RuleSetCompiler([
+ new BasicMatcherRulePlugin("test", "resource"),
+ new BasicMatcherRulePlugin("scheme"),
+ new BasicMatcherRulePlugin("mimetype"),
+ new BasicMatcherRulePlugin("dependency"),
+ new BasicMatcherRulePlugin("include", "resource"),
+ new BasicMatcherRulePlugin("exclude", "resource", true),
+ new BasicMatcherRulePlugin("resource"),
+ new BasicMatcherRulePlugin("resourceQuery"),
+ new BasicMatcherRulePlugin("resourceFragment"),
+ new BasicMatcherRulePlugin("realResource"),
+ new BasicMatcherRulePlugin("issuer"),
+ new BasicMatcherRulePlugin("compiler"),
+ new BasicMatcherRulePlugin("issuerLayer"),
+ new ObjectMatcherRulePlugin("assert", "assertions"),
+ new ObjectMatcherRulePlugin("descriptionData"),
+ new BasicEffectRulePlugin("type"),
+ new BasicEffectRulePlugin("sideEffects"),
+ new BasicEffectRulePlugin("parser"),
+ new BasicEffectRulePlugin("resolve"),
+ new BasicEffectRulePlugin("generator"),
+ new BasicEffectRulePlugin("layer"),
+ new UseEffectRulePlugin()
+]);
+
+class NormalModuleFactory extends ModuleFactory {
+ /**
+ * @param {Object} param params
+ * @param {string=} param.context context
+ * @param {InputFileSystem} param.fs file system
+ * @param {ResolverFactory} param.resolverFactory resolverFactory
+ * @param {ModuleOptions} param.options options
+ * @param {Object=} param.associatedObjectForCache an object to which the cache will be attached
+ * @param {boolean=} param.layers enable layers
+ */
+ constructor({
+ context,
+ fs,
+ resolverFactory,
+ options,
+ associatedObjectForCache,
+ layers = false
+ }) {
+ super();
+ this.hooks = Object.freeze({
+ /** @type {AsyncSeriesBailHook<[ResolveData], Module | false | void>} */
+ resolve: new AsyncSeriesBailHook(["resolveData"]),
+ /** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */
+ resolveForScheme: new HookMap(
+ () => new AsyncSeriesBailHook(["resourceData", "resolveData"])
+ ),
+ /** @type {HookMap<AsyncSeriesBailHook<[ResourceDataWithData, ResolveData], true | void>>} */
+ resolveInScheme: new HookMap(
+ () => new AsyncSeriesBailHook(["resourceData", "resolveData"])
+ ),
+ /** @type {AsyncSeriesBailHook<[ResolveData], Module>} */
+ factorize: new AsyncSeriesBailHook(["resolveData"]),
+ /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
+ beforeResolve: new AsyncSeriesBailHook(["resolveData"]),
+ /** @type {AsyncSeriesBailHook<[ResolveData], false | void>} */
+ afterResolve: new AsyncSeriesBailHook(["resolveData"]),
+ /** @type {AsyncSeriesBailHook<[ResolveData["createData"], ResolveData], Module | void>} */
+ createModule: new AsyncSeriesBailHook(["createData", "resolveData"]),
+ /** @type {SyncWaterfallHook<[Module, ResolveData["createData"], ResolveData], Module>} */
+ module: new SyncWaterfallHook(["module", "createData", "resolveData"]),
+ createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
+ parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
+ createGenerator: new HookMap(
+ () => new SyncBailHook(["generatorOptions"])
+ ),
+ generator: new HookMap(
+ () => new SyncHook(["generator", "generatorOptions"])
+ ),
+ createModuleClass: new HookMap(
+ () => new SyncBailHook(["createData", "resolveData"])
+ )
+ });
+ this.resolverFactory = resolverFactory;
+ this.ruleSet = ruleSetCompiler.compile([
+ {
+ rules: options.defaultRules
+ },
+ {
+ rules: options.rules
+ }
+ ]);
+ this.context = context || "";
+ this.fs = fs;
+ this._globalParserOptions = options.parser;
+ this._globalGeneratorOptions = options.generator;
+ /** @type {Map<string, WeakMap<Object, TODO>>} */
+ this.parserCache = new Map();
+ /** @type {Map<string, WeakMap<Object, Generator>>} */
+ this.generatorCache = new Map();
+ /** @type {Set<Module>} */
+ this._restoredUnsafeCacheEntries = new Set();
+
+ const cacheParseResource = parseResource.bindCache(
+ associatedObjectForCache
+ );
+ const cachedParseResourceWithoutFragment =
+ parseResourceWithoutFragment.bindCache(associatedObjectForCache);
+ this._parseResourceWithoutFragment = cachedParseResourceWithoutFragment;
+
+ this.hooks.factorize.tapAsync(
+ {
+ name: "NormalModuleFactory",
+ stage: 100
+ },
+ (resolveData, callback) => {
+ this.hooks.resolve.callAsync(resolveData, (err, result) => {
+ if (err) return callback(err);
+
+ // Ignored
+ if (result === false) return callback();
+
+ // direct module
+ if (result instanceof Module) return callback(null, result);
+
+ if (typeof result === "object")
+ throw new Error(
+ deprecationChangedHookMessage("resolve", this.hooks.resolve) +
+ " Returning a Module object will result in this module used as result."
+ );
+
+ this.hooks.afterResolve.callAsync(resolveData, (err, result) => {
+ if (err) return callback(err);
+
+ if (typeof result === "object")
+ throw new Error(
+ deprecationChangedHookMessage(
+ "afterResolve",
+ this.hooks.afterResolve
+ )
+ );
+
+ // Ignored
+ if (result === false) return callback();
+
+ const createData = resolveData.createData;
+
+ this.hooks.createModule.callAsync(
+ createData,
+ resolveData,
+ (err, createdModule) => {
+ if (!createdModule) {
+ if (!resolveData.request) {
+ return callback(new Error("Empty dependency (no request)"));
+ }
+
+ // TODO webpack 6 make it required and move javascript/wasm/asset properties to own module
+ createdModule = this.hooks.createModuleClass
+ .for(createData.settings.type)
+ .call(createData, resolveData);
+
+ if (!createdModule) {
+ createdModule = /** @type {Module} */ (
+ new NormalModule(
+ /** @type {NormalModuleCreateData} */ (createData)
+ )
+ );
+ }
+ }
+
+ createdModule = this.hooks.module.call(
+ createdModule,
+ createData,
+ resolveData
+ );
+
+ return callback(null, createdModule);
+ }
+ );
+ });
+ });
+ }
+ );
+ this.hooks.resolve.tapAsync(
+ {
+ name: "NormalModuleFactory",
+ stage: 100
+ },
+ (data, callback) => {
+ const {
+ contextInfo,
+ context,
+ dependencies,
+ dependencyType,
+ request,
+ assertions,
+ resolveOptions,
+ fileDependencies,
+ missingDependencies,
+ contextDependencies
+ } = data;
+ const loaderResolver = this.getResolver("loader");
+
+ /** @type {ResourceData | undefined} */
+ let matchResourceData = undefined;
+ /** @type {string} */
+ let unresolvedResource;
+ /** @type {ParsedLoaderRequest[]} */
+ let elements;
+ let noPreAutoLoaders = false;
+ let noAutoLoaders = false;
+ let noPrePostAutoLoaders = false;
+
+ const contextScheme = getScheme(context);
+ /** @type {string | undefined} */
+ let scheme = getScheme(request);
+
+ if (!scheme) {
+ /** @type {string} */
+ let requestWithoutMatchResource = request;
+ const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request);
+ if (matchResourceMatch) {
+ let matchResource = matchResourceMatch[1];
+ if (matchResource.charCodeAt(0) === 46) {
+ // 46 === ".", 47 === "/"
+ const secondChar = matchResource.charCodeAt(1);
+ if (
+ secondChar === 47 ||
+ (secondChar === 46 && matchResource.charCodeAt(2) === 47)
+ ) {
+ // if matchResources startsWith ../ or ./
+ matchResource = join(this.fs, context, matchResource);
+ }
+ }
+ matchResourceData = {
+ resource: matchResource,
+ ...cacheParseResource(matchResource)
+ };
+ requestWithoutMatchResource = request.slice(
+ matchResourceMatch[0].length
+ );
+ }
+
+ scheme = getScheme(requestWithoutMatchResource);
+
+ if (!scheme && !contextScheme) {
+ const firstChar = requestWithoutMatchResource.charCodeAt(0);
+ const secondChar = requestWithoutMatchResource.charCodeAt(1);
+ noPreAutoLoaders = firstChar === 45 && secondChar === 33; // startsWith "-!"
+ noAutoLoaders = noPreAutoLoaders || firstChar === 33; // startsWith "!"
+ noPrePostAutoLoaders = firstChar === 33 && secondChar === 33; // startsWith "!!";
+ const rawElements = requestWithoutMatchResource
+ .slice(
+ noPreAutoLoaders || noPrePostAutoLoaders
+ ? 2
+ : noAutoLoaders
+ ? 1
+ : 0
+ )
+ .split(/!+/);
+ unresolvedResource = rawElements.pop();
+ elements = rawElements.map(el => {
+ const { path, query } = cachedParseResourceWithoutFragment(el);
+ return {
+ loader: path,
+ options: query ? query.slice(1) : undefined
+ };
+ });
+ scheme = getScheme(unresolvedResource);
+ } else {
+ unresolvedResource = requestWithoutMatchResource;
+ elements = EMPTY_ELEMENTS;
+ }
+ } else {
+ unresolvedResource = request;
+ elements = EMPTY_ELEMENTS;
+ }
+
+ const resolveContext = {
+ fileDependencies,
+ missingDependencies,
+ contextDependencies
+ };
+
+ /** @type {ResourceDataWithData} */
+ let resourceData;
+
+ let loaders;
+
+ const continueCallback = needCalls(2, err => {
+ if (err) return callback(err);
+
+ // translate option idents
+ try {
+ for (const item of loaders) {
+ if (typeof item.options === "string" && item.options[0] === "?") {
+ const ident = item.options.slice(1);
+ if (ident === "[[missing ident]]") {
+ throw new Error(
+ "No ident is provided by referenced loader. " +
+ "When using a function for Rule.use in config you need to " +
+ "provide an 'ident' property for referenced loader options."
+ );
+ }
+ item.options = this.ruleSet.references.get(ident);
+ if (item.options === undefined) {
+ throw new Error(
+ "Invalid ident is provided by referenced loader"
+ );
+ }
+ item.ident = ident;
+ }
+ }
+ } catch (e) {
+ return callback(e);
+ }
+
+ if (!resourceData) {
+ // ignored
+ return callback(null, dependencies[0].createIgnoredModule(context));
+ }
+
+ const userRequest =
+ (matchResourceData !== undefined
+ ? `${matchResourceData.resource}!=!`
+ : "") +
+ stringifyLoadersAndResource(loaders, resourceData.resource);
+
+ const settings = {};
+ const useLoadersPost = [];
+ const useLoaders = [];
+ const useLoadersPre = [];
+
+ // handle .webpack[] suffix
+ let resource;
+ let match;
+ if (
+ matchResourceData &&
+ typeof (resource = matchResourceData.resource) === "string" &&
+ (match = /\.webpack\[([^\]]+)\]$/.exec(resource))
+ ) {
+ settings.type = match[1];
+ matchResourceData.resource = matchResourceData.resource.slice(
+ 0,
+ -settings.type.length - 10
+ );
+ } else {
+ settings.type = JAVASCRIPT_MODULE_TYPE_AUTO;
+ const resourceDataForRules = matchResourceData || resourceData;
+ const result = this.ruleSet.exec({
+ resource: resourceDataForRules.path,
+ realResource: resourceData.path,
+ resourceQuery: resourceDataForRules.query,
+ resourceFragment: resourceDataForRules.fragment,
+ scheme,
+ assertions,
+ mimetype: matchResourceData
+ ? ""
+ : resourceData.data.mimetype || "",
+ dependency: dependencyType,
+ descriptionData: matchResourceData
+ ? undefined
+ : resourceData.data.descriptionFileData,
+ issuer: contextInfo.issuer,
+ compiler: contextInfo.compiler,
+ issuerLayer: contextInfo.issuerLayer || ""
+ });
+ for (const r of result) {
+ // https://github.com/webpack/webpack/issues/16466
+ // if a request exists PrePostAutoLoaders, should disable modifying Rule.type
+ if (r.type === "type" && noPrePostAutoLoaders) {
+ continue;
+ }
+ if (r.type === "use") {
+ if (!noAutoLoaders && !noPrePostAutoLoaders) {
+ useLoaders.push(r.value);
+ }
+ } else if (r.type === "use-post") {
+ if (!noPrePostAutoLoaders) {
+ useLoadersPost.push(r.value);
+ }
+ } else if (r.type === "use-pre") {
+ if (!noPreAutoLoaders && !noPrePostAutoLoaders) {
+ useLoadersPre.push(r.value);
+ }
+ } else if (
+ typeof r.value === "object" &&
+ r.value !== null &&
+ typeof settings[r.type] === "object" &&
+ settings[r.type] !== null
+ ) {
+ settings[r.type] = cachedCleverMerge(settings[r.type], r.value);
+ } else {
+ settings[r.type] = r.value;
+ }
+ }
+ }
+
+ let postLoaders, normalLoaders, preLoaders;
+
+ const continueCallback = needCalls(3, err => {
+ if (err) {
+ return callback(err);
+ }
+ const allLoaders = postLoaders;
+ if (matchResourceData === undefined) {
+ for (const loader of loaders) allLoaders.push(loader);
+ for (const loader of normalLoaders) allLoaders.push(loader);
+ } else {
+ for (const loader of normalLoaders) allLoaders.push(loader);
+ for (const loader of loaders) allLoaders.push(loader);
+ }
+ for (const loader of preLoaders) allLoaders.push(loader);
+ let type = settings.type;
+ const resolveOptions = settings.resolve;
+ const layer = settings.layer;
+ if (layer !== undefined && !layers) {
+ return callback(
+ new Error(
+ "'Rule.layer' is only allowed when 'experiments.layers' is enabled"
+ )
+ );
+ }
+ try {
+ Object.assign(data.createData, {
+ layer:
+ layer === undefined ? contextInfo.issuerLayer || null : layer,
+ request: stringifyLoadersAndResource(
+ allLoaders,
+ resourceData.resource
+ ),
+ userRequest,
+ rawRequest: request,
+ loaders: allLoaders,
+ resource: resourceData.resource,
+ context:
+ resourceData.context || getContext(resourceData.resource),
+ matchResource: matchResourceData
+ ? matchResourceData.resource
+ : undefined,
+ resourceResolveData: resourceData.data,
+ settings,
+ type,
+ parser: this.getParser(type, settings.parser),
+ parserOptions: settings.parser,
+ generator: this.getGenerator(type, settings.generator),
+ generatorOptions: settings.generator,
+ resolveOptions
+ });
+ } catch (e) {
+ return callback(e);
+ }
+ callback();
+ });
+ this.resolveRequestArray(
+ contextInfo,
+ this.context,
+ useLoadersPost,
+ loaderResolver,
+ resolveContext,
+ (err, result) => {
+ postLoaders = result;
+ continueCallback(err);
+ }
+ );
+ this.resolveRequestArray(
+ contextInfo,
+ this.context,
+ useLoaders,
+ loaderResolver,
+ resolveContext,
+ (err, result) => {
+ normalLoaders = result;
+ continueCallback(err);
+ }
+ );
+ this.resolveRequestArray(
+ contextInfo,
+ this.context,
+ useLoadersPre,
+ loaderResolver,
+ resolveContext,
+ (err, result) => {
+ preLoaders = result;
+ continueCallback(err);
+ }
+ );
+ });
+
+ this.resolveRequestArray(
+ contextInfo,
+ contextScheme ? this.context : context,
+ elements,
+ loaderResolver,
+ resolveContext,
+ (err, result) => {
+ if (err) return continueCallback(err);
+ loaders = result;
+ continueCallback();
+ }
+ );
+
+ const defaultResolve = context => {
+ if (/^($|\?)/.test(unresolvedResource)) {
+ resourceData = {
+ resource: unresolvedResource,
+ data: {},
+ ...cacheParseResource(unresolvedResource)
+ };
+ continueCallback();
+ }
+
+ // resource without scheme and with path
+ else {
+ const normalResolver = this.getResolver(
+ "normal",
+ dependencyType
+ ? cachedSetProperty(
+ resolveOptions || EMPTY_RESOLVE_OPTIONS,
+ "dependencyType",
+ dependencyType
+ )
+ : resolveOptions
+ );
+ this.resolveResource(
+ contextInfo,
+ context,
+ unresolvedResource,
+ normalResolver,
+ resolveContext,
+ (err, resolvedResource, resolvedResourceResolveData) => {
+ if (err) return continueCallback(err);
+ if (resolvedResource !== false) {
+ resourceData = {
+ resource: resolvedResource,
+ data: resolvedResourceResolveData,
+ ...cacheParseResource(resolvedResource)
+ };
+ }
+ continueCallback();
+ }
+ );
+ }
+ };
+
+ // resource with scheme
+ if (scheme) {
+ resourceData = {
+ resource: unresolvedResource,
+ data: {},
+ path: undefined,
+ query: undefined,
+ fragment: undefined,
+ context: undefined
+ };
+ this.hooks.resolveForScheme
+ .for(scheme)
+ .callAsync(resourceData, data, err => {
+ if (err) return continueCallback(err);
+ continueCallback();
+ });
+ }
+
+ // resource within scheme
+ else if (contextScheme) {
+ resourceData = {
+ resource: unresolvedResource,
+ data: {},
+ path: undefined,
+ query: undefined,
+ fragment: undefined,
+ context: undefined
+ };
+ this.hooks.resolveInScheme
+ .for(contextScheme)
+ .callAsync(resourceData, data, (err, handled) => {
+ if (err) return continueCallback(err);
+ if (!handled) return defaultResolve(this.context);
+ continueCallback();
+ });
+ }
+
+ // resource without scheme and without path
+ else defaultResolve(context);
+ }
+ );
+ }
+
+ cleanupForCache() {
+ for (const module of this._restoredUnsafeCacheEntries) {
+ ChunkGraph.clearChunkGraphForModule(module);
+ ModuleGraph.clearModuleGraphForModule(module);
+ module.cleanupForCache();
+ }
+ }
+
+ /**
+ * @param {ModuleFactoryCreateData} data data object
+ * @param {function((Error | null)=, ModuleFactoryResult=): void} callback callback
+ * @returns {void}
+ */
+ create(data, callback) {
+ const dependencies = /** @type {ModuleDependency[]} */ (data.dependencies);
+ const context = data.context || this.context;
+ const resolveOptions = data.resolveOptions || EMPTY_RESOLVE_OPTIONS;
+ const dependency = dependencies[0];
+ const request = dependency.request;
+ const assertions = dependency.assertions;
+ const contextInfo = data.contextInfo;
+ const fileDependencies = new LazySet();
+ const missingDependencies = new LazySet();
+ const contextDependencies = new LazySet();
+ const dependencyType =
+ (dependencies.length > 0 && dependencies[0].category) || "";
+ /** @type {ResolveData} */
+ const resolveData = {
+ contextInfo,
+ resolveOptions,
+ context,
+ request,
+ assertions,
+ dependencies,
+ dependencyType,
+ fileDependencies,
+ missingDependencies,
+ contextDependencies,
+ createData: {},
+ cacheable: true
+ };
+ this.hooks.beforeResolve.callAsync(resolveData, (err, result) => {
+ if (err) {
+ return callback(err, {
+ fileDependencies,
+ missingDependencies,
+ contextDependencies,
+ cacheable: false
+ });
+ }
+
+ // Ignored
+ if (result === false) {
+ return callback(null, {
+ fileDependencies,
+ missingDependencies,
+ contextDependencies,
+ cacheable: resolveData.cacheable
+ });
+ }
+
+ if (typeof result === "object")
+ throw new Error(
+ deprecationChangedHookMessage(
+ "beforeResolve",
+ this.hooks.beforeResolve
+ )
+ );
+
+ this.hooks.factorize.callAsync(resolveData, (err, module) => {
+ if (err) {
+ return callback(err, {
+ fileDependencies,
+ missingDependencies,
+ contextDependencies,
+ cacheable: false
+ });
+ }
+
+ const factoryResult = {
+ module,
+ fileDependencies,
+ missingDependencies,
+ contextDependencies,
+ cacheable: resolveData.cacheable
+ };
+
+ callback(null, factoryResult);
+ });
+ });
+ }
+
+ resolveResource(
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolver,
+ resolveContext,
+ callback
+ ) {
+ resolver.resolve(
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolveContext,
+ (err, resolvedResource, resolvedResourceResolveData) => {
+ if (err) {
+ return this._resolveResourceErrorHints(
+ err,
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolver,
+ resolveContext,
+ (err2, hints) => {
+ if (err2) {
+ err.message += `
+A fatal error happened during resolving additional hints for this error: ${err2.message}`;
+ err.stack += `
+
+A fatal error happened during resolving additional hints for this error:
+${err2.stack}`;
+ return callback(err);
+ }
+ if (hints && hints.length > 0) {
+ err.message += `
+${hints.join("\n\n")}`;
+ }
+
+ // Check if the extension is missing a leading dot (e.g. "js" instead of ".js")
+ let appendResolveExtensionsHint = false;
+ const specifiedExtensions = Array.from(
+ resolver.options.extensions
+ );
+ const expectedExtensions = specifiedExtensions.map(extension => {
+ if (LEADING_DOT_EXTENSION_REGEX.test(extension)) {
+ appendResolveExtensionsHint = true;
+ return `.${extension}`;
+ }
+ return extension;
+ });
+ if (appendResolveExtensionsHint) {
+ err.message += `\nDid you miss the leading dot in 'resolve.extensions'? Did you mean '${JSON.stringify(
+ expectedExtensions
+ )}' instead of '${JSON.stringify(specifiedExtensions)}'?`;
+ }
+
+ callback(err);
+ }
+ );
+ }
+ callback(err, resolvedResource, resolvedResourceResolveData);
+ }
+ );
+ }
+
+ _resolveResourceErrorHints(
+ error,
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolver,
+ resolveContext,
+ callback
+ ) {
+ asyncLib.parallel(
+ [
+ callback => {
+ if (!resolver.options.fullySpecified) return callback();
+ resolver
+ .withOptions({
+ fullySpecified: false
+ })
+ .resolve(
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolveContext,
+ (err, resolvedResource) => {
+ if (!err && resolvedResource) {
+ const resource = parseResource(resolvedResource).path.replace(
+ /^.*[\\/]/,
+ ""
+ );
+ return callback(
+ null,
+ `Did you mean '${resource}'?
+BREAKING CHANGE: The request '${unresolvedResource}' failed to resolve only because it was resolved as fully specified
+(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
+The extension in the request is mandatory for it to be fully specified.
+Add the extension to the request.`
+ );
+ }
+ callback();
+ }
+ );
+ },
+ callback => {
+ if (!resolver.options.enforceExtension) return callback();
+ resolver
+ .withOptions({
+ enforceExtension: false,
+ extensions: []
+ })
+ .resolve(
+ contextInfo,
+ context,
+ unresolvedResource,
+ resolveContext,
+ (err, resolvedResource) => {
+ if (!err && resolvedResource) {
+ let hint = "";
+ const match = /(\.[^.]+)(\?|$)/.exec(unresolvedResource);
+ if (match) {
+ const fixedRequest = unresolvedResource.replace(
+ /(\.[^.]+)(\?|$)/,
+ "$2"
+ );
+ if (resolver.options.extensions.has(match[1])) {
+ hint = `Did you mean '${fixedRequest}'?`;
+ } else {
+ hint = `Did you mean '${fixedRequest}'? Also note that '${match[1]}' is not in 'resolve.extensions' yet and need to be added for this to work?`;
+ }
+ } else {
+ hint = `Did you mean to omit the extension or to remove 'resolve.enforceExtension'?`;
+ }
+ return callback(
+ null,
+ `The request '${unresolvedResource}' failed to resolve only because 'resolve.enforceExtension' was specified.
+${hint}
+Including the extension in the request is no longer possible. Did you mean to enforce including the extension in requests with 'resolve.extensions: []' instead?`
+ );
+ }
+ callback();
+ }
+ );
+ },
+ callback => {
+ if (
+ /^\.\.?\//.test(unresolvedResource) ||
+ resolver.options.preferRelative
+ ) {
+ return callback();
+ }
+ resolver.resolve(
+ contextInfo,
+ context,
+ `./${unresolvedResource}`,
+ resolveContext,
+ (err, resolvedResource) => {
+ if (err || !resolvedResource) return callback();
+ const moduleDirectories = resolver.options.modules
+ .map(m => (Array.isArray(m) ? m.join(", ") : m))
+ .join(", ");
+ callback(
+ null,
+ `Did you mean './${unresolvedResource}'?
+Requests that should resolve in the current directory need to start with './'.
+Requests that start with a name are treated as module requests and resolve within module directories (${moduleDirectories}).
+If changing the source code is not an option there is also a resolve options called 'preferRelative' which tries to resolve these kind of requests in the current directory too.`
+ );
+ }
+ );
+ }
+ ],
+ (err, hints) => {
+ if (err) return callback(err);
+ callback(null, hints.filter(Boolean));
+ }
+ );
+ }
+
+ resolveRequestArray(
+ contextInfo,
+ context,
+ array,
+ resolver,
+ resolveContext,
+ callback
+ ) {
+ if (array.length === 0) return callback(null, array);
+ asyncLib.map(
+ array,
+ (item, callback) => {
+ resolver.resolve(
+ contextInfo,
+ context,
+ item.loader,
+ resolveContext,
+ (err, result, resolveRequest) => {
+ if (
+ err &&
+ /^[^/]*$/.test(item.loader) &&
+ !/-loader$/.test(item.loader)
+ ) {
+ return resolver.resolve(
+ contextInfo,
+ context,
+ item.loader + "-loader",
+ resolveContext,
+ err2 => {
+ if (!err2) {
+ err.message =
+ err.message +
+ "\n" +
+ "BREAKING CHANGE: It's no longer allowed to omit the '-loader' suffix when using loaders.\n" +
+ ` You need to specify '${item.loader}-loader' instead of '${item.loader}',\n` +
+ " see https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed";
+ }
+ callback(err);
+ }
+ );
+ }
+ if (err) return callback(err);
+
+ const parsedResult = this._parseResourceWithoutFragment(result);
+
+ const type = /\.mjs$/i.test(parsedResult.path)
+ ? "module"
+ : /\.cjs$/i.test(parsedResult.path)
+ ? "commonjs"
+ : resolveRequest.descriptionFileData === undefined
+ ? undefined
+ : resolveRequest.descriptionFileData.type;
+
+ const resolved = {
+ loader: parsedResult.path,
+ type,
+ options:
+ item.options === undefined
+ ? parsedResult.query
+ ? parsedResult.query.slice(1)
+ : undefined
+ : item.options,
+ ident: item.options === undefined ? undefined : item.ident
+ };
+ return callback(null, resolved);
+ }
+ );
+ },
+ callback
+ );
+ }
+
+ getParser(type, parserOptions = EMPTY_PARSER_OPTIONS) {
+ let cache = this.parserCache.get(type);
+
+ if (cache === undefined) {
+ cache = new WeakMap();
+ this.parserCache.set(type, cache);
+ }
+
+ let parser = cache.get(parserOptions);
+
+ if (parser === undefined) {
+ parser = this.createParser(type, parserOptions);
+ cache.set(parserOptions, parser);
+ }
+
+ return parser;
+ }
+
+ /**
+ * @param {string} type type
+ * @param {{[k: string]: any}} parserOptions parser options
+ * @returns {Parser} parser
+ */
+ createParser(type, parserOptions = {}) {
+ parserOptions = mergeGlobalOptions(
+ this._globalParserOptions,
+ type,
+ parserOptions
+ );
+ const parser = this.hooks.createParser.for(type).call(parserOptions);
+ if (!parser) {
+ throw new Error(`No parser registered for ${type}`);
+ }
+ this.hooks.parser.for(type).call(parser, parserOptions);
+ return parser;
+ }
+
+ getGenerator(type, generatorOptions = EMPTY_GENERATOR_OPTIONS) {
+ let cache = this.generatorCache.get(type);
+
+ if (cache === undefined) {
+ cache = new WeakMap();
+ this.generatorCache.set(type, cache);
+ }
+
+ let generator = cache.get(generatorOptions);
+
+ if (generator === undefined) {
+ generator = this.createGenerator(type, generatorOptions);
+ cache.set(generatorOptions, generator);
+ }
+
+ return generator;
+ }
+
+ createGenerator(type, generatorOptions = {}) {
+ generatorOptions = mergeGlobalOptions(
+ this._globalGeneratorOptions,
+ type,
+ generatorOptions
+ );
+ const generator = this.hooks.createGenerator
+ .for(type)
+ .call(generatorOptions);
+ if (!generator) {
+ throw new Error(`No generator registered for ${type}`);
+ }
+ this.hooks.generator.for(type).call(generator, generatorOptions);
+ return generator;
+ }
+
+ getResolver(type, resolveOptions) {
+ return this.resolverFactory.get(type, resolveOptions);
+ }
+}
+
+module.exports = NormalModuleFactory;