From cb01f0e76f199877ca10b5df31688db9fc7487df Mon Sep 17 00:00:00 2001 From: nightwing Date: Sun, 12 Apr 2015 21:45:42 +0400 Subject: [PATCH] add config support to mini require --- .../build_support/mini_require.js | 159 ++++++++++++++++-- 1 file changed, 141 insertions(+), 18 deletions(-) diff --git a/node_modules/architect-build/build_support/mini_require.js b/node_modules/architect-build/build_support/mini_require.js index ad08d9c3..60194f04 100644 --- a/node_modules/architect-build/build_support/mini_require.js +++ b/node_modules/architect-build/build_support/mini_require.js @@ -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;