diff options
Diffstat (limited to 'node_modules/webpack/lib/NormalModuleFactory.js')
| -rw-r--r-- | node_modules/webpack/lib/NormalModuleFactory.js | 1166 |
1 files changed, 0 insertions, 1166 deletions
diff --git a/node_modules/webpack/lib/NormalModuleFactory.js b/node_modules/webpack/lib/NormalModuleFactory.js deleted file mode 100644 index a0d8b767..00000000 --- a/node_modules/webpack/lib/NormalModuleFactory.js +++ /dev/null @@ -1,1166 +0,0 @@ -/* - 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; |
