webpack/require-polyfill.js

153 lines
4.6 KiB
JavaScript
Raw Normal View History

2012-03-10 20:11:23 +08:00
// Polyfill for node.js
2012-03-21 19:41:03 +08:00
// - adds require.ensure
// - adds require.context
2012-04-03 22:26:08 +08:00
// call it like this:
2012-03-21 19:41:03 +08:00
// require = require("webpack/require-polyfill")(require.valueOf());
// This is only required when you want to use the special require.xxx methods
// in server-side code which should be so only in rar cases.
2012-03-10 20:11:23 +08:00
module.exports = function(req) {
2012-03-21 19:41:03 +08:00
if(!req.webpackPolyfill) {
var oldReq = req;
req = function(name) {
2012-03-27 06:00:32 +08:00
if(name.indexOf("!") !== -1) {
2012-04-07 09:20:45 +08:00
var items = name.replace(/^!|!$/g, "").replace(/!!/g, "!").split(/!/g);
2012-03-27 06:00:32 +08:00
var resource = oldReq.resolve(items.pop());
var resolved = [];
items.forEach(function(item, index) {
var relative = false;
if(item.length > 2 &&
item[0] === ".") {
if(item[1] === "/")
relative = true;
else if(item.length > 3 &&
item[1] === "." &&
item[2] === "/")
relative = true;
}
if(item.length > 3 &&
item[1] === ":" &&
item[2] === "\\")
relative = true;
var tries = [];
if(!relative) {
2012-04-07 09:20:45 +08:00
module.exports.options.resolve.loaderPostfixes.forEach(function(postfix) {
2012-03-27 06:00:32 +08:00
if(item.indexOf("/") !== -1)
tries.push(item.replace("/", postfix+"/"));
else
tries.push(item + postfix);
});
}
tries.push(item);
2012-04-07 09:20:45 +08:00
var extensions = module.exports.options.resolve.loaderExtensions;
2012-03-27 06:00:32 +08:00
for(var i = 0; i < tries.length; i++) {
for(var ext = 0; ext < extensions.length; ext++) {
try {
var file = oldReq.resolve(tries[i] + extensions[ext]);
} catch(e) {}
if(file) {
resolved.push(file);
break;
}
}
if(ext !== extensions.length)
break;
}
if(i === tries.length)
throw new Error("Cannot find loader module '"+item+"'");
});
resolved = resolved.reverse();
var cacheLine = resolved.join("!") + "!" + resource;
var cacheEntry = oldReq.cache[cacheLine];
if(cacheEntry)
return cacheEntry;
var content = [require("fs").readFileSync(resource, "utf-8")];
2012-04-03 22:26:08 +08:00
var values;
function exec(code, filename) {
var Module = require("module");
var m = new Module("exec in " + cacheLine, module);
2012-05-01 21:42:01 +08:00
m.filename = resource;
m.paths = Module._nodeModulePaths(require("path").dirname(resource));
m._compile("require = require(" + JSON.stringify(__filename) + ")(require.valueOf());" + code, filename);
2012-04-03 22:26:08 +08:00
return m.exports;
}
2012-03-27 06:00:32 +08:00
resolved.forEach(function(loader) {
2012-04-03 22:26:08 +08:00
var set = false, err = null;
var context = {
2012-03-27 06:00:32 +08:00
request: cacheLine,
2012-04-03 22:26:08 +08:00
filenames: [resource],
exec: exec,
2012-05-01 21:42:01 +08:00
resolve: function(context, path, cb) {
try {
var Module = require("module");
var virtModule = new Module(".", null);
virtModule.filename = require("path").join(context, "resolve.js");
virtModule.paths = Module._nodeModulePaths(context);
cb(null, Module._resolveFilename(path, virtModule));
} catch(e) { cb(e); }
},
2012-04-03 22:26:08 +08:00
async: function() { return false; },
callback: function() {
set = true;
content = Array.prototype.slice.apply(arguments);
err = content.shift();
values = context.values;
},
2012-04-07 09:20:45 +08:00
options: module.exports.options,
minimize: module.exports.options.minimize,
debug: module.exports.options.debug,
web: false,
2012-04-03 22:26:08 +08:00
inputValues: values,
values: undefined
};
var retVal = oldReq(loader).apply(context, content);
if(set) {
if(err) throw err;
} else {
content = [retVal];
values = context.values;
}
2012-03-27 06:00:32 +08:00
});
2012-04-03 22:26:08 +08:00
if(values !== undefined)
return values[0];
return exec(content[0], cacheLine);
2012-04-07 09:20:45 +08:00
} else {
var resolved = oldReq.resolve(name);
var match = false;
2012-04-07 10:13:26 +08:00
var loaders = module.exports.options.resolve.loaders;
2012-04-07 09:20:45 +08:00
for(var i = 0; i < loaders.length; i++)
if(loaders[i].test.test(resolved))
2012-04-08 03:57:02 +08:00
return req(loaders[i].loader + "!" + name);
2012-04-07 09:20:45 +08:00
2012-03-27 06:00:32 +08:00
return oldReq(name);
2012-04-07 09:20:45 +08:00
}
2012-03-21 19:41:03 +08:00
};
req.__proto__ = oldReq;
req.webpackPolyfill = true;
}
2012-03-10 20:11:23 +08:00
if(!req.ensure) {
req.ensure = function(array, callback) {
callback(req);
};
}
2012-03-11 20:44:38 +08:00
if(!req.context) {
req.context = function(contextName) {
return function(name) {
return req(contextName + "/" + name);
}
}
}
2012-03-21 19:41:03 +08:00
return req;
2012-03-27 06:00:32 +08:00
}
2012-04-07 09:20:45 +08:00
var options = module.exports.options = {
resolve: {
loaders: [
{test: /\.coffee$/, loader: "coffee"},
// {test: /\.json$/, loader: "json"}, // This works out of the box in node.js
{test: /\.jade$/, loader: "jade"},
2012-05-04 22:42:38 +08:00
{test: /\.css$/, loader: "style!css"},
{test: /\.less$/, loader: "style!css!val!less"}
2012-04-07 09:20:45 +08:00
],
loaderExtensions: [".webpack-loader.js", ".loader.js", ".js", ""],
loaderPostfixes: ["-webpack-loader", "-loader", ""]
}
};