add config support to mini require

pull/85/head
nightwing 2015-04-12 21:45:42 +04:00 zatwierdzone przez nightwing
rodzic dddeef97ae
commit cb01f0e76f
1 zmienionych plików z 141 dodań i 18 usunięć

Wyświetl plik

@ -1,3 +1,4 @@
console.time("req");
(function() {
var MODULE_LOAD_URL = "/load/module";
@ -6,14 +7,17 @@ var global = (function() { return this; })();
if (!global && typeof window != "undefined") global = window; // can happen in strict mode
var commentRegExp = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;
var cjsRequireRegExp = /[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g;
var cjsRequireRegExp = /require\s*\(\s*["']([^'"\s]+)["']\s*\)/g;
function getInlineDeps(fn) {
var deps = [];
if (fn.length) {
fn.toString().replace(commentRegExp, "")
.replace(cjsRequireRegExp, function (match, dep) {
deps.push(dep);
.replace(cjsRequireRegExp, function (match, dep, index, str) {
var i = index;
while (str.charCodeAt(i-=1) <= 32) {}
if (str.charAt(i) !== ".")
deps.push(dep);
});
deps = ["require", "exports", "module"].concat(deps);
}
@ -49,12 +53,32 @@ var define = function(name, deps, callback) {
exports: {},
packaged: true
};
if (define.loading[name])
delete define.loading[name];
if (define.lastModule)
define.pending.push(name);
else
define.lastModule = name;
};
var defQueue = [];
var addToLoadQueue = function(missing, deps, callback) {
define.queue.push(function() { _require('', deps, callback); });
for (var i = 0; i < missing.length; ++i)
require.load(missing[i]);
var toLoad = missing.length;
var map = {};
define.queue.push({
deps: deps,
map: map,
toLoad: toLoad,
callback: callback
});
for (var i = 0; i < missing.length; ++i) {
var p = missing[i];
map[p] = 1;
if (!define.loading[p]) {
require.load(p);
define.loading[p] = 1;
}
}
};
var processLoadQueue = function(err, id) {
@ -64,16 +88,38 @@ var processLoadQueue = function(err, id) {
if (defQueue.length > 1)
throw new Error("more than one module in defqueue");
define(id, defQueue[0][0], defQueue[0][1]);
defQueue.length = 0;
defQueue.length = 0;
}
var pending = define.pending;
var changed = false;
define.queue.forEach(function(r) {
pending.forEach(function(id) {
if (r.map[id])
r.toLoad--;
});
if (r.map[define.lastModule])
r.toLoad--;
if (!r.toLoad) {
changed = true;
_require("", r.deps, r.callback);
}
});
define.lastModule = null;
if (pending.length)
define.pending = [];
if (changed) {
define.queue = define.queue.filter(function(r) {
return r.toLoad;
});
}
var queue = define.queue;
define.queue = [];
queue.forEach(function(f) { f(); });
};
define.amd = true;
define.queue = [];
define.loaded = {};
define.loading = {};
define.pending = [];
define.modules = { require: 1, exports: 1, module: 1 };
define.fetchedUrls = {};
@ -103,7 +149,7 @@ var activateModule = function(name) {
? module.factory.apply(module, args.map(lookup))
: module.factory(req, exports, module);
exports = returnValue || module.exports;
exports = returnValue == undefined ? module.exports : returnValue;
}
delete define.loaded[name];
define.modules[name] = exports;
@ -155,7 +201,7 @@ var _require = function(parentId, moduleName, callback) {
}
}
if (_require.original)
return _require.original.apply(this, arguments);
return _require.original.call(this, moduleName, callback);
};
var normalizeName = function(parentId, moduleName) {
@ -188,9 +234,28 @@ var require = function(module, callback) {
return _require("", module, callback);
};
var config = require.config = function(cfg) {
config.baseUrl = cfg.baseUrl.replace(/\/*$/, "/");
cfg.packages && cfg.packages.forEach(function(pkg) {
if (typeof pkg === "string") pkg = { name: pkg };
config.packages[pkg.name] = {
name: pkg.name,
location: (pkg.location || pkg.name).replace(/\/*$/, "/"),
main: (pkg.main || "main").replace(/\.js$/, "").replace(/^\.\//, "")
};
});
cfg.paths && Object.keys(cfg.paths).forEach(function(p) {
config.paths[p] = cfg.paths[p];
});
};
config.packages = Object.create(null);
config.paths = Object.create(null);
require.undef = function(module, callback) {
module = normalizeName("", module);
var path = require.toUrl(module);
var path = require.toUrl(module, ".js");
delete define.loaded[module];
delete define.modules[module];
delete define.fetchedUrls[path];
@ -198,9 +263,40 @@ require.undef = function(module, callback) {
require.MODULE_LOAD_URL = MODULE_LOAD_URL;
require.toUrl = function(module, ext) {
var path = module;
if (!/https?:\/\//.test(path))
require.toUrl = function(moduleName, ext, skipExt) {
var absRe = /^([\w\+\.\-]+:|\/)/;
if (config.baseUrl) {
var index = moduleName.indexOf("!");
if (index !== -1 || !ext)
ext = "";
var paths = config.paths;
var pkgs = config.packages;
var testPath = moduleName, tail = "";
while (testPath) {
if (paths[testPath]) {
moduleName = paths[testPath] + tail;
break;
}
if (pkgs[testPath]) {
moduleName = pkgs[testPath].location + (tail || pkgs[testPath].main);
break;
}
var i = testPath.lastIndexOf("/");
if (i === -1) break;
tail = testPath.substr(i) + tail;
testPath = testPath.slice(0, i);
}
var url = moduleName + ext;
if (!absRe.test(url)) url = config.baseUrl + url;
return url;
}
var path = moduleName;
if (!absRe.test(path))
path = require.MODULE_LOAD_URL + "/" + path + (ext || "");
return path;
};
@ -209,7 +305,7 @@ var loadScript = function(path, id, callback) {
var head = document.head || document.documentElement;
var s = document.createElement("script");
s.src = path;
s.charset = 'utf-8';
s.charset = "utf-8";
s.async = true;
if (path.lastIndexOf(require.MODULE_LOAD_URL, 0) == 0)
@ -231,8 +327,21 @@ require.load = function(module) {
if (i) {
var plugin = module.substring(0, i);
module = module.substr(i);
if (require[plugin]) {
if (typeof require[plugin] == "function") {
require[plugin](module, processLoadQueue);
} else if (config.baseUrl) {
if (require[plugin])
return require[plugin][plugin + module] = 1;
require[plugin] = Object.create(null);
require[plugin][plugin + module] = 1;
require([plugin.slice(0, -1)], function(p) {
var pending = require[plugin];
definePlugin(plugin, p);
Object.keys(pending).forEach(function(p) {
delete define.loading[p];
});
require(Object.keys(pending));
});
} else {
console.error("require plugin " + plugin + "missing");
}
@ -245,6 +354,17 @@ require.load = function(module) {
}
};
function definePlugin(plugin, p) {
require[plugin] = function(moduleName, processLoadQueue) {
p.load(moduleName, require, function(value) {
define(plugin + moduleName, [], function() {
return value;
});
processLoadQueue();
});
};
}
/*** plugins ***/
require["text!"] = function(module, callback) {
var url = require.toUrl(module);
@ -275,6 +395,9 @@ if (!global.require || !global.require.packaged) {
global.require = require;
global.require.packaged = true;
}
if (!global.requirejs) global.requirejs = require;
global.miniRequire = require;