webpack
Version:
Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jade, coffee, css, less, ... and your custom stuff.
99 lines (86 loc) • 3.63 kB
JavaScript
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Jason Anderson @diurnalist
*/
var REGEXP_HASH = /\[hash(?::(\d+))?\]/gi,
REGEXP_CHUNKHASH = /\[chunkhash(?::(\d+))?\]/gi,
REGEXP_NAME = /\[name\]/gi,
REGEXP_ID = /\[id\]/gi,
REGEXP_FILE = /\[file\]/gi,
REGEXP_QUERY = /\[query\]/gi,
REGEXP_FILEBASE = /\[filebase\]/gi;
// Using global RegExp for .test is dangerous
// We use a normal RegExp instead of .test
var REGEXP_HASH_FOR_TEST = new RegExp(REGEXP_HASH.source, "i"),
REGEXP_CHUNKHASH_FOR_TEST = new RegExp(REGEXP_CHUNKHASH.source, "i"),
REGEXP_NAME_FOR_TEST = new RegExp(REGEXP_NAME.source, "i");
// Backwards compatibility; expose regexes on Template object
var Template = require("./Template");
Template.REGEXP_HASH = REGEXP_HASH;
Template.REGEXP_CHUNKHASH = REGEXP_CHUNKHASH;
Template.REGEXP_NAME = REGEXP_NAME;
Template.REGEXP_ID = REGEXP_ID;
Template.REGEXP_FILE = REGEXP_FILE;
Template.REGEXP_QUERY = REGEXP_QUERY;
Template.REGEXP_FILEBASE = REGEXP_FILEBASE;
function TemplatedPathPlugin() {}
module.exports = TemplatedPathPlugin;
function withHashLength(replacer, handlerFn) {
return function (_, hashLength) {
var length = hashLength && parseInt(hashLength, 10);
if(length && handlerFn) {
return handlerFn(length);
}
var hash = replacer.apply(this, arguments);
return length ? hash.slice(0, length) : hash;
};
}
function getReplacer(value, allowEmpty) {
return function (match) {
// last argument in replacer is the entire input string
var input = arguments[arguments.length - 1];
if (value == null) {
if (!allowEmpty) throw new Error("Path variable " + match + " not implemented in this context: " + input);
return "";
} else {
return "" + value;
}
};
}
function replacePathVariables(path, data) {
var chunk = data.chunk;
var chunkId = chunk && chunk.id;
var chunkName = chunk && (chunk.name || chunk.id);
var chunkHash = chunk && (chunk.renderedHash || chunk.hash);
var chunkHashWithLength = chunk && chunk.hashWithLength;
return path
.replace(REGEXP_HASH, withHashLength(getReplacer(data.hash)))
.replace(REGEXP_CHUNKHASH, withHashLength(getReplacer(chunkHash), chunkHashWithLength))
.replace(REGEXP_ID, getReplacer(chunkId))
.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));
}
TemplatedPathPlugin.prototype.constructor = TemplatedPathPlugin;
TemplatedPathPlugin.prototype.apply = function(compiler) {
compiler.plugin("compilation", function(compilation) {
var mainTemplate = compilation.mainTemplate;
mainTemplate.plugin("asset-path", replacePathVariables);
mainTemplate.plugin("global-hash", function(chunk, paths) {
var outputOptions = this.outputOptions;
var publicPath = outputOptions.publicPath || "";
var filename = outputOptions.filename || "";
var chunkFilename = outputOptions.chunkFilename || "";
if(REGEXP_HASH_FOR_TEST.test(publicPath) || REGEXP_CHUNKHASH_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) || REGEXP_CHUNKHASH_FOR_TEST.test(chunkFilename) || REGEXP_NAME_FOR_TEST.test(chunkFilename))
return true;
if(REGEXP_HASH_FOR_TEST.test(paths.join("|")))
return true;
});
});
};