模块化管理组件v0.1
我也来个version。
发表下我的require.js v0.1.
提供出来,看谁敢用!
View Code
/* author jiajiaobj@163.com(zhus) reference from seajs thanks for lifesinger@gmail.com (Frank Wang) require function ====> require(["uriA","uriB"],function(A,B){ //we can do something here; }); define function ====> define(["depsA","depsB"],function(){ }) */ (function(ns) { //namespace Require //Outside access can not Require = {}; //In order to achieve closure Require.globals = { basePath: "", anonymousMod: null, currentScript: null, activeScript: null, loadedUris: {} }; Require.fn = { getSrc: function(node) { var src = ""; if (node.nodeName.toLowerCase() === "script") { return node.hasAttribute ? // non-IE6/7 node.getAttribute('src', 0): node.src; // see http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx } return node.lastChild && arguments.callee(node.lastChild); }, dirname: function(path) { var s = path.match(/.*(?=\/.*$)/); return (s ? s[0] : '.') + '/'; }, /*dirName: function(uri) { var dir; return dir = uri.replace(/\/[^\/]*$/, ""); },*/ isAbsolutePath: function(uri) { return~uri.indexOf('://') || uri.indexOf('//') === 0; }, isRelativePath: function(id) { return id.indexOf('./') === 0 || id.indexOf('../') === 0; }, isRootPath: function(id) { return id.charAt(0) === '/' && id.charAt(1) !== '/'; }, isTopLevelPath: function(id) { var c = id.charAt(0); return id.indexOf('://') === - 1 && c !== '.' && c !== '/'; }, //get the asset we needed getAsset: function(uri, callback) { var isCSS = /\.css(?:\?|$)/i.test(uri); if (isCSS) { this.loadCSS(uri, callback); } else { this.loadScript(uri, callback); } return uri; }, //create "script" tag and appendTo head //load the script file loadScript: function(uri, callback) { var __self__ = this, head = document.head || document.getElementsByTagName('head')[0] || document.documentElement, node = document.createElement("script"); node.src = this.resolveUri(uri); node.onload = node.onerror = node.onreadystatechange = function() { if (/loaded|complete|undefine/.test(node.readyState)) { node.onload = node.onerror = node.onreadystatechange = null; if (node.parentNode) { //node.parentNode.removeChild(node); } var mod = Require.anonymousMod; if (mod) { if (!Require.globals.loadedUris[uri]) { __self__.memoize(uri, mod); } Require.anonymousMod = null; } else if (Require.globals.activeScript) { Require.globals.activeScript = null; } else { //__self__.memoize(uri, new __self__.Module(uri, [], function() {})); } callback && callback(); } }; // For some cache cases in IE 6-9, the script executes IMMEDIATELY after // the end of the insertBefore execution, so use `Require.globals.currentScript` // to hold current node, for deriving url in `define`. Require.globals.currentScript = node; head.appendChild(node); Require.globals.currentScript = null; return node; }, // For IE6-9 browsers, the script onload event may not fire right // after the the script is evaluated. Kris Zyp found that it // could query the script nodes and the one that is in "interactive" // mode indicates the current script. // Ref: http://goo.gl/JHfFW getCurrentScript: function() { if (Require.globals.currentScript) { return Require.globals.currentScript; } // For IE6-9 browsers, the script onload event may not fire right // after the the script is evaluated. Kris Zyp found that it // could query the script nodes and the one that is in "interactive" // mode indicates the current script. // Ref: http://goo.gl/JHfFW if (Require.globals.activeScript && Require.globals.activeScript.readyState === 'interactive') { return Require.globals.activeScript; } var head = document.head || document.getElementsByTagName('head')[0] || document.documentElement; var scripts = head.getElementsByTagName('script'); for (var i = 0; i < scripts.length; i++) { var script = scripts[i]; if (script.readyState === 'interactive') { Require.globals.activeScript = script; return script; } } }, toId: function(uri) { return Require.fn.resolveUri(uri.replace(/\.js*$/, "")); }, //create "link" tag and set it's href to "ooxx.css" and appendTo head loadCSS: function(uri, callback) { var __self__ = this, head = document.head || document.getElementsByTagName('head')[0] || document.documentElement, node = document.createElement("link"); node.rel = "stylesheet"; node.href = uri; node.onload = node.onerror = node.onreadystatechange = function() { if (/loaded|complete|undefine/.test(node.readyState)) { node.onload = node.onerror = node.onreadystatechange = null; if (!Require.globals.loadedUris[uri]) { __self__.memoize(uri, new __self__.Module(uri, [], function() {})); } callback && callback(); } } head.appendChild(node); return node; }, //resolve uri to "ooxx.js" or "ooxx.css" resolveUri: function(uri) { if (this.isRelativePath(uri)) { uri = Require.globals.basePath + uri.replace(/^\.\//, ''); } if (!this.isAbsolutePath(uri)) { //uri = Require.globals.basePath + "/" + uri.replace(/^\.\//, ''); } if (uri.indexOf('?') === - 1 && ! /\.(?:css|js)$/.test(uri)) { uri += '.js'; } return uri; }, //Module constructor. //@param id => "id" id of module //@param deps => ["deps01","deps02"] dependencies. //@param mod = > function the factory of the module Module: function(id, deps, mod) { this.id = id; this.deps = deps; this.mod = mod; }, //Cache module to "Require.globals.loadedUris" memoize: function(uri, mod) { mod.id = uri; Require.globals.loadedUris[uri] = mod; }, //Define a module define: function(requires, module) { var id = undefined, deps = requires, mod = module, uri, ua = navigator.userAgent; if (/msie/.test(ua.toLowerCase())) { var script = Require.fn.getCurrentScript(); if (script) { //uri = (script.hasAttribute ? // non-IE6/7 //script.src: // see http://msdn.microsoft.com/en-us/library/ms536429(VS.85).aspx //script.getAttribute('src', 4)); //uri = script.src; if (script.hasAttribute) { uri = script.getAttribute('src', 4); } else { uri = script.src; } } } mod = new Require.fn.Module(id, deps, module); if (uri) { Require.fn.memoize(Require.fn.toId(Require.fn.resolveUri(uri)), mod); //Require.fn.memoize(Require.fn.toId(uri), mod); } else { Require.anonymousMod = mod; } }, //set the uri ready for "uri.ready = true" //@param uris ["uri01","uri02"] setReadyState: function(uris) { for (var i = 0, l = uris.length; i < l; i++) { var el = Require.globals.loadedUris[Require.fn.resolveUri(uris[i])]; if (el) { el.ready = true; if (el.mod) { el.mod(); } } } }, //get the uri which ready != true //@param uris ["uri01","uri02"] getUnReadyUris: function(uris) { var unReadyUris = []; for (var i = 0, l = uris.length; i < l; i++) { var mod = Require.globals.loadedUris[Require.fn.resolveUri(uris[i])]; if (!mod || ! mod.ready) { unReadyUris.push(Require.fn.resolveUri(uris[i])); } } return unReadyUris; }, //Provides modules to the environment. //@param uris=>["uri01","uri02"] //@param callback=>function will happened when uris is ready provide: function(uris, callback) { var unReadyUris = this.getUnReadyUris(uris), fn = arguments.callee, __self__ = this; for (var i = 0, l = unReadyUris.length, n = l; i < l; i++) { (function(uri) { if (Require.globals.loadedUris[uri]) { onload(); } else { __self__.getAsset(uri, onload); } function onload() { var mod = Require.globals.loadedUris[uri]; if (mod) { var deps = mod.deps; var m = deps.length; if (m) { n += m; fn.call(__self__, deps, function() { n -= m; if (n === 0) onProvide(mod); }); } } if (--n === 0) onProvide(mod); } })(unReadyUris[i]); } function onProvide(mod) { __self__.setReadyState(unReadyUris); callback(); } } }; if (Require.globals.basePath == "") { var uri = Require.fn.getSrc(document); path = Require.fn.dirname(uri); Require.globals.basePath = path; } //Expose interfaces //Assigned to the arguments => ns; ns.require = function(uris, callback) { Require.fn.provide(uris, function() { var args = [], el; for (var i = 0, l = uris.length; i < l; i++) { el = Require.globals.loadedUris[Require.fn.resolveUri(uris[i])]; if (el && el.mod) { args.push(el.mod()); } } callback && callback.apply(null, args); }); }; ns.define = Require.fn.define; })(this);
使用方法:
api:
define:define(["a.js","b.js"],function(){
window.moduleA=moduleA;
return {
methodA:methodA,
methodB:methodB
};
})
require:require(["a","b"],function(a, b){
a.methodA();
b.methodB();
})
尽管不尽完善,但是貌似可以凑合用了,兼容ie7-9, firefox最新版,
ie6没测试。。。。
做个记录,没事翻翻,哈哈