diff options
Diffstat (limited to 'node_modules/webpack/lib/NormalModule.js')
-rw-r--r-- | node_modules/webpack/lib/NormalModule.js | 582 |
1 files changed, 0 insertions, 582 deletions
diff --git a/node_modules/webpack/lib/NormalModule.js b/node_modules/webpack/lib/NormalModule.js deleted file mode 100644 index 76aa1bd..0000000 --- a/node_modules/webpack/lib/NormalModule.js +++ /dev/null @@ -1,582 +0,0 @@ -/* - MIT License http://www.opensource.org/licenses/mit-license.php - Author Tobias Koppers @sokra -*/ -"use strict"; - -const NativeModule = require("module"); - -const { - CachedSource, - LineToLineMappedSource, - OriginalSource, - RawSource, - SourceMapSource -} = require("webpack-sources"); -const { getContext, runLoaders } = require("loader-runner"); - -const WebpackError = require("./WebpackError"); -const Module = require("./Module"); -const ModuleParseError = require("./ModuleParseError"); -const ModuleBuildError = require("./ModuleBuildError"); -const ModuleError = require("./ModuleError"); -const ModuleWarning = require("./ModuleWarning"); -const createHash = require("./util/createHash"); -const contextify = require("./util/identifier").contextify; - -/** @typedef {import("./util/createHash").Hash} Hash */ - -const asString = buf => { - if (Buffer.isBuffer(buf)) { - return buf.toString("utf-8"); - } - return buf; -}; - -const asBuffer = str => { - if (!Buffer.isBuffer(str)) { - return Buffer.from(str, "utf-8"); - } - return str; -}; - -class NonErrorEmittedError extends WebpackError { - constructor(error) { - super(); - - this.name = "NonErrorEmittedError"; - this.message = "(Emitted value instead of an instance of Error) " + error; - - Error.captureStackTrace(this, this.constructor); - } -} - -/** - * @typedef {Object} CachedSourceEntry - * @property {TODO} source the generated source - * @property {string} hash the hash value - */ - -class NormalModule extends Module { - constructor({ - type, - request, - userRequest, - rawRequest, - loaders, - resource, - matchResource, - parser, - generator, - resolveOptions - }) { - super(type, getContext(resource)); - - // Info from Factory - this.request = request; - this.userRequest = userRequest; - this.rawRequest = rawRequest; - this.binary = type.startsWith("webassembly"); - this.parser = parser; - this.generator = generator; - this.resource = resource; - this.matchResource = matchResource; - this.loaders = loaders; - if (resolveOptions !== undefined) this.resolveOptions = resolveOptions; - - // Info from Build - this.error = null; - this._source = null; - this._sourceSize = null; - this._buildHash = ""; - this.buildTimestamp = undefined; - /** @private @type {Map<string, CachedSourceEntry>} */ - this._cachedSources = new Map(); - - // Options for the NormalModule set by plugins - // TODO refactor this -> options object filled from Factory - this.useSourceMap = false; - this.lineToLine = false; - - // Cache - this._lastSuccessfulBuildMeta = {}; - } - - identifier() { - return this.request; - } - - readableIdentifier(requestShortener) { - return requestShortener.shorten(this.userRequest); - } - - libIdent(options) { - return contextify(options.context, this.userRequest); - } - - nameForCondition() { - const resource = this.matchResource || this.resource; - const idx = resource.indexOf("?"); - if (idx >= 0) return resource.substr(0, idx); - return resource; - } - - updateCacheModule(module) { - this.type = module.type; - this.request = module.request; - this.userRequest = module.userRequest; - this.rawRequest = module.rawRequest; - this.parser = module.parser; - this.generator = module.generator; - this.resource = module.resource; - this.matchResource = module.matchResource; - this.loaders = module.loaders; - this.resolveOptions = module.resolveOptions; - } - - createSourceForAsset(name, content, sourceMap) { - if (!sourceMap) { - return new RawSource(content); - } - - if (typeof sourceMap === "string") { - return new OriginalSource(content, sourceMap); - } - - return new SourceMapSource(content, name, sourceMap); - } - - createLoaderContext(resolver, options, compilation, fs) { - const requestShortener = compilation.runtimeTemplate.requestShortener; - const getCurrentLoaderName = () => { - const currentLoader = this.getCurrentLoader(loaderContext); - if (!currentLoader) return "(not in loader scope)"; - return requestShortener.shorten(currentLoader.loader); - }; - const loaderContext = { - version: 2, - emitWarning: warning => { - if (!(warning instanceof Error)) { - warning = new NonErrorEmittedError(warning); - } - this.warnings.push( - new ModuleWarning(this, warning, { - from: getCurrentLoaderName() - }) - ); - }, - emitError: error => { - if (!(error instanceof Error)) { - error = new NonErrorEmittedError(error); - } - this.errors.push( - new ModuleError(this, error, { - from: getCurrentLoaderName() - }) - ); - }, - getLogger: name => { - const currentLoader = this.getCurrentLoader(loaderContext); - return compilation.getLogger(() => - [currentLoader && currentLoader.loader, name, this.identifier()] - .filter(Boolean) - .join("|") - ); - }, - // TODO remove in webpack 5 - exec: (code, filename) => { - // @ts-ignore Argument of type 'this' is not assignable to parameter of type 'Module'. - const module = new NativeModule(filename, this); - // @ts-ignore _nodeModulePaths is deprecated and undocumented Node.js API - module.paths = NativeModule._nodeModulePaths(this.context); - module.filename = filename; - module._compile(code, filename); - return module.exports; - }, - resolve(context, request, callback) { - resolver.resolve({}, context, request, {}, callback); - }, - getResolve(options) { - const child = options ? resolver.withOptions(options) : resolver; - return (context, request, callback) => { - if (callback) { - child.resolve({}, context, request, {}, callback); - } else { - return new Promise((resolve, reject) => { - child.resolve({}, context, request, {}, (err, result) => { - if (err) reject(err); - else resolve(result); - }); - }); - } - }; - }, - emitFile: (name, content, sourceMap, assetInfo) => { - if (!this.buildInfo.assets) { - this.buildInfo.assets = Object.create(null); - this.buildInfo.assetsInfo = new Map(); - } - this.buildInfo.assets[name] = this.createSourceForAsset( - name, - content, - sourceMap - ); - this.buildInfo.assetsInfo.set(name, assetInfo); - }, - rootContext: options.context, - webpack: true, - sourceMap: !!this.useSourceMap, - mode: options.mode || "production", - _module: this, - _compilation: compilation, - _compiler: compilation.compiler, - fs: fs - }; - - compilation.hooks.normalModuleLoader.call(loaderContext, this); - if (options.loader) { - Object.assign(loaderContext, options.loader); - } - - return loaderContext; - } - - getCurrentLoader(loaderContext, index = loaderContext.loaderIndex) { - if ( - this.loaders && - this.loaders.length && - index < this.loaders.length && - index >= 0 && - this.loaders[index] - ) { - return this.loaders[index]; - } - return null; - } - - createSource(source, resourceBuffer, sourceMap) { - // if there is no identifier return raw source - if (!this.identifier) { - return new RawSource(source); - } - - // from here on we assume we have an identifier - const identifier = this.identifier(); - - if (this.lineToLine && resourceBuffer) { - return new LineToLineMappedSource( - source, - identifier, - asString(resourceBuffer) - ); - } - - if (this.useSourceMap && sourceMap) { - return new SourceMapSource(source, identifier, sourceMap); - } - - if (Buffer.isBuffer(source)) { - // @ts-ignore - // TODO We need to fix @types/webpack-sources to allow RawSource to take a Buffer | string - return new RawSource(source); - } - - return new OriginalSource(source, identifier); - } - - doBuild(options, compilation, resolver, fs, callback) { - const loaderContext = this.createLoaderContext( - resolver, - options, - compilation, - fs - ); - - runLoaders( - { - resource: this.resource, - loaders: this.loaders, - context: loaderContext, - readResource: fs.readFile.bind(fs) - }, - (err, result) => { - if (result) { - this.buildInfo.cacheable = result.cacheable; - this.buildInfo.fileDependencies = new Set(result.fileDependencies); - this.buildInfo.contextDependencies = new Set( - result.contextDependencies - ); - } - - if (err) { - if (!(err instanceof Error)) { - err = new NonErrorEmittedError(err); - } - const currentLoader = this.getCurrentLoader(loaderContext); - const error = new ModuleBuildError(this, err, { - from: - currentLoader && - compilation.runtimeTemplate.requestShortener.shorten( - currentLoader.loader - ) - }); - return callback(error); - } - - const resourceBuffer = result.resourceBuffer; - const source = result.result[0]; - const sourceMap = result.result.length >= 1 ? result.result[1] : null; - const extraInfo = result.result.length >= 2 ? result.result[2] : null; - - if (!Buffer.isBuffer(source) && typeof source !== "string") { - const currentLoader = this.getCurrentLoader(loaderContext, 0); - const err = new Error( - `Final loader (${ - currentLoader - ? compilation.runtimeTemplate.requestShortener.shorten( - currentLoader.loader - ) - : "unknown" - }) didn't return a Buffer or String` - ); - const error = new ModuleBuildError(this, err); - return callback(error); - } - - this._source = this.createSource( - this.binary ? asBuffer(source) : asString(source), - resourceBuffer, - sourceMap - ); - this._sourceSize = null; - this._ast = - typeof extraInfo === "object" && - extraInfo !== null && - extraInfo.webpackAST !== undefined - ? extraInfo.webpackAST - : null; - return callback(); - } - ); - } - - markModuleAsErrored(error) { - // Restore build meta from successful build to keep importing state - this.buildMeta = Object.assign({}, this._lastSuccessfulBuildMeta); - this.error = error; - this.errors.push(this.error); - this._source = new RawSource( - "throw new Error(" + JSON.stringify(this.error.message) + ");" - ); - this._sourceSize = null; - this._ast = null; - } - - applyNoParseRule(rule, content) { - // must start with "rule" if rule is a string - if (typeof rule === "string") { - return content.indexOf(rule) === 0; - } - - if (typeof rule === "function") { - return rule(content); - } - // we assume rule is a regexp - return rule.test(content); - } - - // check if module should not be parsed - // returns "true" if the module should !not! be parsed - // returns "false" if the module !must! be parsed - shouldPreventParsing(noParseRule, request) { - // if no noParseRule exists, return false - // the module !must! be parsed. - if (!noParseRule) { - return false; - } - - // we only have one rule to check - if (!Array.isArray(noParseRule)) { - // returns "true" if the module is !not! to be parsed - return this.applyNoParseRule(noParseRule, request); - } - - for (let i = 0; i < noParseRule.length; i++) { - const rule = noParseRule[i]; - // early exit on first truthy match - // this module is !not! to be parsed - if (this.applyNoParseRule(rule, request)) { - return true; - } - } - // no match found, so this module !should! be parsed - return false; - } - - _initBuildHash(compilation) { - const hash = createHash(compilation.outputOptions.hashFunction); - if (this._source) { - hash.update("source"); - this._source.updateHash(hash); - } - hash.update("meta"); - hash.update(JSON.stringify(this.buildMeta)); - this._buildHash = /** @type {string} */ (hash.digest("hex")); - } - - build(options, compilation, resolver, fs, callback) { - this.buildTimestamp = Date.now(); - this.built = true; - this._source = null; - this._sourceSize = null; - this._ast = null; - this._buildHash = ""; - this.error = null; - this.errors.length = 0; - this.warnings.length = 0; - this.buildMeta = {}; - this.buildInfo = { - cacheable: false, - fileDependencies: new Set(), - contextDependencies: new Set(), - assets: undefined, - assetsInfo: undefined - }; - - return this.doBuild(options, compilation, resolver, fs, err => { - this._cachedSources.clear(); - - // if we have an error mark module as failed and exit - if (err) { - this.markModuleAsErrored(err); - this._initBuildHash(compilation); - return callback(); - } - - // check if this module should !not! be parsed. - // if so, exit here; - const noParseRule = options.module && options.module.noParse; - if (this.shouldPreventParsing(noParseRule, this.request)) { - this._initBuildHash(compilation); - return callback(); - } - - const handleParseError = e => { - const source = this._source.source(); - const loaders = this.loaders.map(item => - contextify(options.context, item.loader) - ); - const error = new ModuleParseError(this, source, e, loaders); - this.markModuleAsErrored(error); - this._initBuildHash(compilation); - return callback(); - }; - - const handleParseResult = result => { - this._lastSuccessfulBuildMeta = this.buildMeta; - this._initBuildHash(compilation); - return callback(); - }; - - try { - const result = this.parser.parse( - this._ast || this._source.source(), - { - current: this, - module: this, - compilation: compilation, - options: options - }, - (err, result) => { - if (err) { - handleParseError(err); - } else { - handleParseResult(result); - } - } - ); - if (result !== undefined) { - // parse is sync - handleParseResult(result); - } - } catch (e) { - handleParseError(e); - } - }); - } - - getHashDigest(dependencyTemplates) { - // TODO webpack 5 refactor - let dtHash = dependencyTemplates.get("hash"); - return `${this.hash}-${dtHash}`; - } - - source(dependencyTemplates, runtimeTemplate, type = "javascript") { - const hashDigest = this.getHashDigest(dependencyTemplates); - const cacheEntry = this._cachedSources.get(type); - if (cacheEntry !== undefined && cacheEntry.hash === hashDigest) { - // We can reuse the cached source - return cacheEntry.source; - } - - const source = this.generator.generate( - this, - dependencyTemplates, - runtimeTemplate, - type - ); - - const cachedSource = new CachedSource(source); - this._cachedSources.set(type, { - source: cachedSource, - hash: hashDigest - }); - return cachedSource; - } - - originalSource() { - return this._source; - } - - needRebuild(fileTimestamps, contextTimestamps) { - // always try to rebuild in case of an error - if (this.error) return true; - - // always rebuild when module is not cacheable - if (!this.buildInfo.cacheable) return true; - - // Check timestamps of all dependencies - // Missing timestamp -> need rebuild - // Timestamp bigger than buildTimestamp -> need rebuild - for (const file of this.buildInfo.fileDependencies) { - const timestamp = fileTimestamps.get(file); - if (!timestamp) return true; - if (timestamp >= this.buildTimestamp) return true; - } - for (const file of this.buildInfo.contextDependencies) { - const timestamp = contextTimestamps.get(file); - if (!timestamp) return true; - if (timestamp >= this.buildTimestamp) return true; - } - // elsewise -> no rebuild needed - return false; - } - - size() { - if (this._sourceSize === null) { - this._sourceSize = this._source ? this._source.size() : -1; - } - return this._sourceSize; - } - - /** - * @param {Hash} hash the hash used to track dependencies - * @returns {void} - */ - updateHash(hash) { - hash.update(this._buildHash); - super.updateHash(hash); - } -} - -module.exports = NormalModule; |