diff options
Diffstat (limited to 'node_modules/webpack/lib/TemplatedPathPlugin.js')
-rw-r--r-- | node_modules/webpack/lib/TemplatedPathPlugin.js | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/node_modules/webpack/lib/TemplatedPathPlugin.js b/node_modules/webpack/lib/TemplatedPathPlugin.js new file mode 100644 index 0000000..d463f51 --- /dev/null +++ b/node_modules/webpack/lib/TemplatedPathPlugin.js @@ -0,0 +1,188 @@ +/* + MIT License http://www.opensource.org/licenses/mit-license.php + Author Jason Anderson @diurnalist +*/ +"use strict"; + +const REGEXP_HASH = /\[hash(?::(\d+))?\]/gi, + REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/gi, + REGEXP_MODULEHASH = /\[modulehash(?::(\d+))?\]/gi, + REGEXP_CONTENTHASH = /\[contenthash(?::(\d+))?\]/gi, + REGEXP_NAME = /\[name\]/gi, + REGEXP_ID = /\[id\]/gi, + REGEXP_MODULEID = /\[moduleid\]/gi, + REGEXP_FILE = /\[file\]/gi, + REGEXP_QUERY = /\[query\]/gi, + REGEXP_FILEBASE = /\[filebase\]/gi, + REGEXP_URL = /\[url\]/gi; + +// Using global RegExp for .test is dangerous +// We use a normal RegExp instead of .test +const REGEXP_HASH_FOR_TEST = new RegExp(REGEXP_HASH.source, "i"), + REGEXP_CHUNKHASH_FOR_TEST = new RegExp(REGEXP_CHUNKHASH.source, "i"), + REGEXP_CONTENTHASH_FOR_TEST = new RegExp(REGEXP_CONTENTHASH.source, "i"), + REGEXP_NAME_FOR_TEST = new RegExp(REGEXP_NAME.source, "i"); + +const withHashLength = (replacer, handlerFn, assetInfo) => { + const fn = (match, hashLength, ...args) => { + if (assetInfo) assetInfo.immutable = true; + const length = hashLength && parseInt(hashLength, 10); + if (length && handlerFn) { + return handlerFn(length); + } + const hash = replacer(match, hashLength, ...args); + return length ? hash.slice(0, length) : hash; + }; + return fn; +}; + +const getReplacer = (value, allowEmpty) => { + const fn = (match, ...args) => { + // last argument in replacer is the entire input string + const input = args[args.length - 1]; + if (value === null || value === undefined) { + if (!allowEmpty) { + throw new Error( + `Path variable ${match} not implemented in this context: ${input}` + ); + } + return ""; + } else { + return `${escapePathVariables(value)}`; + } + }; + return fn; +}; + +const escapePathVariables = value => { + return typeof value === "string" + ? value.replace(/\[(\\*[\w:]+\\*)\]/gi, "[\\$1\\]") + : value; +}; + +const replacePathVariables = (path, data, assetInfo) => { + const chunk = data.chunk; + const chunkId = chunk && chunk.id; + const chunkName = chunk && (chunk.name || chunk.id); + const chunkHash = chunk && (chunk.renderedHash || chunk.hash); + const chunkHashWithLength = chunk && chunk.hashWithLength; + const contentHashType = data.contentHashType; + const contentHash = + (chunk && chunk.contentHash && chunk.contentHash[contentHashType]) || + data.contentHash; + const contentHashWithLength = + (chunk && + chunk.contentHashWithLength && + chunk.contentHashWithLength[contentHashType]) || + data.contentHashWithLength; + const module = data.module; + const moduleId = module && module.id; + const moduleHash = module && (module.renderedHash || module.hash); + const moduleHashWithLength = module && module.hashWithLength; + + if (typeof path === "function") { + path = path(data); + } + + if ( + data.noChunkHash && + (REGEXP_CHUNKHASH_FOR_TEST.test(path) || + REGEXP_CONTENTHASH_FOR_TEST.test(path)) + ) { + throw new Error( + `Cannot use [chunkhash] or [contenthash] for chunk in '${path}' (use [hash] instead)` + ); + } + + return ( + path + .replace( + REGEXP_HASH, + withHashLength(getReplacer(data.hash), data.hashWithLength, assetInfo) + ) + .replace( + REGEXP_CHUNKHASH, + withHashLength(getReplacer(chunkHash), chunkHashWithLength, assetInfo) + ) + .replace( + REGEXP_CONTENTHASH, + withHashLength( + getReplacer(contentHash), + contentHashWithLength, + assetInfo + ) + ) + .replace( + REGEXP_MODULEHASH, + withHashLength(getReplacer(moduleHash), moduleHashWithLength, assetInfo) + ) + .replace(REGEXP_ID, getReplacer(chunkId)) + .replace(REGEXP_MODULEID, getReplacer(moduleId)) + .replace(REGEXP_NAME, getReplacer(chunkName)) + .replace(REGEXP_FILE, getReplacer(data.filename)) + .replace(REGEXP_FILEBASE, getReplacer(data.basename)) + // query is optional, it's OK if it's in a path but there's nothing to replace it with + .replace(REGEXP_QUERY, getReplacer(data.query, true)) + // only available in sourceMappingURLComment + .replace(REGEXP_URL, getReplacer(data.url)) + .replace(/\[\\(\\*[\w:]+\\*)\\\]/gi, "[$1]") + ); +}; + +class TemplatedPathPlugin { + apply(compiler) { + compiler.hooks.compilation.tap("TemplatedPathPlugin", compilation => { + const mainTemplate = compilation.mainTemplate; + + mainTemplate.hooks.assetPath.tap( + "TemplatedPathPlugin", + replacePathVariables + ); + + mainTemplate.hooks.globalHash.tap( + "TemplatedPathPlugin", + (chunk, paths) => { + const outputOptions = mainTemplate.outputOptions; + const publicPath = outputOptions.publicPath || ""; + const filename = outputOptions.filename || ""; + const chunkFilename = + outputOptions.chunkFilename || outputOptions.filename; + if ( + REGEXP_HASH_FOR_TEST.test(publicPath) || + REGEXP_CHUNKHASH_FOR_TEST.test(publicPath) || + REGEXP_CONTENTHASH_FOR_TEST.test(publicPath) || + REGEXP_NAME_FOR_TEST.test(publicPath) + ) + return true; + if (REGEXP_HASH_FOR_TEST.test(filename)) return true; + if (REGEXP_HASH_FOR_TEST.test(chunkFilename)) return true; + if (REGEXP_HASH_FOR_TEST.test(paths.join("|"))) return true; + } + ); + + mainTemplate.hooks.hashForChunk.tap( + "TemplatedPathPlugin", + (hash, chunk) => { + const outputOptions = mainTemplate.outputOptions; + const chunkFilename = + outputOptions.chunkFilename || outputOptions.filename; + if (REGEXP_CHUNKHASH_FOR_TEST.test(chunkFilename)) { + hash.update(JSON.stringify(chunk.getChunkMaps(true).hash)); + } + if (REGEXP_CONTENTHASH_FOR_TEST.test(chunkFilename)) { + hash.update( + JSON.stringify( + chunk.getChunkMaps(true).contentHash.javascript || {} + ) + ); + } + if (REGEXP_NAME_FOR_TEST.test(chunkFilename)) { + hash.update(JSON.stringify(chunk.getChunkMaps(true).name)); + } + } + ); + }); + } +} + +module.exports = TemplatedPathPlugin; |