模块化管理组件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没测试。。。。

做个记录,没事翻翻,哈哈

posted @ 2012-05-31 11:21  潴哥  阅读(315)  评论(0编辑  收藏  举报