webpack/lib/ContextModule.js

192 lines
5.7 KiB
JavaScript
Raw Normal View History

2013-01-31 01:49:25 +08:00
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var Module = require("./Module");
2013-03-26 23:54:41 +08:00
var OriginalSource = require("webpack-core/lib/OriginalSource");
2013-10-14 19:59:44 +08:00
var RawSource = require("webpack-core/lib/RawSource");
var DependenciesBlock = require("./DependenciesBlock");
2013-01-31 01:49:25 +08:00
function ContextModule(resolveDependencies, context, recursive, regExp, addon, async) {
2013-01-31 01:49:25 +08:00
Module.call(this);
this.resolveDependencies = resolveDependencies;
this.context = context;
this.recursive = recursive;
this.regExp = regExp;
this.addon = addon;
this.async = !!async;
2013-01-31 01:49:25 +08:00
this.cacheable = true;
this.contextDependencies = [context];
this.built = false;
}
module.exports = ContextModule;
ContextModule.prototype = Object.create(Module.prototype);
ContextModule.prototype.identifier = function() {
var identifier = "";
identifier += this.context + " ";
if(this.async)
identifier += "async ";
2013-01-31 01:49:25 +08:00
if(!this.recursive)
identifier += "nonrecursive ";
if(this.addon)
identifier += this.addon;
if(this.regExp)
identifier += this.regExp;
return identifier.replace(/ $/, "");
};
function prettyRegExp(str) {
return str.substring(1, str.length - 1);
}
ContextModule.prototype.readableIdentifier = function(requestShortener) {
var identifier = "";
identifier += requestShortener.shorten(this.context) + " ";
if(this.asnyc)
identifier += "asnyc ";
2013-01-31 01:49:25 +08:00
if(!this.recursive)
identifier += "nonrecursive ";
if(this.addon)
2013-02-04 19:34:20 +08:00
identifier += requestShortener.shorten(this.addon);
2013-01-31 01:49:25 +08:00
if(this.regExp)
identifier += prettyRegExp(this.regExp + "");
return identifier.replace(/ $/, "");
};
ContextModule.prototype.needRebuild = function(fileTimestamps, contextTimestamps) {
var ts = contextTimestamps[this.context];
if(!ts) return true;
2013-02-01 15:03:38 +08:00
return ts >= this.builtTime;
2013-01-31 01:49:25 +08:00
};
2013-02-01 01:00:22 +08:00
ContextModule.prototype.disconnect = function disconnect() {
this.built = false;
Module.prototype.disconnect.call(this);
};
2013-01-31 01:49:25 +08:00
ContextModule.prototype.build = function(options, compilation, resolver, fs, callback) {
this.built = true;
this.builtTime = new Date().getTime();
var addon = this.addon;
this.resolveDependencies(fs, this.context, this.recursive, this.regExp, function(err, dependencies) {
if(err) return callback(err);
2014-10-12 17:24:42 +08:00
if(dependencies) {
dependencies.forEach(function(dep) {
2015-05-11 00:31:58 +08:00
dep.loc = dep.userRequest;
2014-10-12 17:24:42 +08:00
dep.userRequest = dep.request;
dep.request = addon + dep.userRequest;
});
}
if(this.async) {
this.blocks = dependencies && dependencies.map(function(dep) {
var block = new DependenciesBlock();
block.dependencies = [dep];
return block;
});
} else {
this.dependencies = dependencies;
}
2013-01-31 01:49:25 +08:00
callback();
}.bind(this));
};
2015-04-24 05:55:50 +08:00
ContextModule.prototype.source = function() {
var str;
var map = {};
2014-10-12 17:24:42 +08:00
if(this.dependencies && this.dependencies.length > 0) {
2015-04-24 05:55:50 +08:00
this.dependencies.slice().sort(function(a, b) {
2014-07-26 20:48:42 +08:00
if(a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1;
}).forEach(function(dep) {
if(dep.module)
2015-04-24 05:55:50 +08:00
map[dep.userRequest] = dep.module.id;
2014-07-26 20:48:42 +08:00
});
2015-04-24 05:55:50 +08:00
str = [
2014-07-26 20:48:42 +08:00
"var map = ", JSON.stringify(map, null, "\t"), ";\n",
"function webpackContext(req) {\n",
"\treturn __webpack_require__(webpackContextResolve(req));\n",
"};\n",
"function webpackContextResolve(req) {\n",
"\tvar id = map[req];\n",
"\tif(!(id + 1)) // check for number\n",
"\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n",
"\treturn id;\n",
2014-07-26 20:48:42 +08:00
"};\n",
"webpackContext.keys = function webpackContextKeys() {\n",
"\treturn Object.keys(map);\n",
"};\n",
"webpackContext.resolve = webpackContextResolve;\n",
"module.exports = webpackContext;\n",
2015-04-24 05:55:50 +08:00
"webpackContext.id = " + this.id + ";\n"
2014-07-26 20:48:42 +08:00
];
} else if(this.blocks && this.blocks.length > 0) {
var items = this.blocks.map(function(block) {
return {
dependency: block.dependencies[0],
block: block,
userRequest: block.dependencies[0].userRequest
};
}).filter(function(item) {
return item.dependency.module;
});
var hasMultipleChunks = false;
items.sort(function(a, b) {
if(a.userRequest === b.userRequest) return 0;
return a.userRequest < b.userRequest ? -1 : 1;
}).forEach(function(item) {
if(item.dependency.module) {
if(item.block.chunks.length > 1)
hasMultipleChunks = true;
map[item.userRequest] = [item.dependency.module.id].concat(item.block.chunks.map(function(chunk) {
return chunk.id;
}));
}
});
str = [
"var map = ", JSON.stringify(map, null, "\t"), ";\n",
"function webpackAsyncContext(req) {\n",
"\tvar ids = map[req];",
"\tif(!ids)\n",
"\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n",
"\treturn ",
hasMultipleChunks ?
"Promise.all(ids.slice(1).map(__webpack_require__.e))" :
"__webpack_require__.e(ids[1])",
".then(function() {\n",
"\t\treturn __webpack_require__(ids[0]);\n",
"\t});\n",
"};\n",
"webpackAsyncContext.keys = function webpackAsyncContextKeys() {\n",
"\treturn Object.keys(map);\n",
"};\n",
"module.exports = webpackAsyncContext;\n",
"webpackAsyncContext.id = " + this.id + ";\n"
];
2014-07-26 20:48:42 +08:00
} else {
2015-04-24 05:55:50 +08:00
str = [
"function webpackEmptyContext(req) {\n",
2014-07-26 20:48:42 +08:00
"\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n",
"}\n",
"webpackEmptyContext.keys = function() { return []; };\n",
"webpackEmptyContext.resolve = webpackEmptyContext;\n",
"module.exports = webpackEmptyContext;\n",
"webpackEmptyContext.id = " + this.id + ";\n"
2014-07-26 20:48:42 +08:00
];
}
2013-10-14 19:59:44 +08:00
if(this.useSourceMap) {
return new OriginalSource(str.join(""), this.identifier());
} else {
return new RawSource(str.join(""));
}
2013-01-31 01:49:25 +08:00
};
ContextModule.prototype.size = function() {
return this.dependencies.map(function(dep) {
return dep.userRequest.length + 5;
2015-07-13 06:20:09 +08:00
}).reduce(function(a, b) {
return a + b;
}, 160);
};