Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CommonJS, AMD, CMD 和 原生 JS 一些感悟 #3

Open
pfan123 opened this issue May 4, 2017 · 0 comments
Open

CommonJS, AMD, CMD 和 原生 JS 一些感悟 #3

pfan123 opened this issue May 4, 2017 · 0 comments
Labels

Comments

@pfan123
Copy link
Owner

pfan123 commented May 4, 2017

CommonJS, AMD, CMD 和 原生 JS 一些感悟

模块标准

CommonJS

Node应用由模块组成,采用CommonJS模块规范。

根据这个规范,每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。

如果想要对外提供接口的话,可以将接口绑定到 exports (即 module.exports) 上,推荐使用 module.exports(一个页面代表一个模块)。

CommandJS写法示例:

//先创建一个 check_commonjs.js 的文件
var flag = true;

function check(){
    return flag;
}

module.exports = check


//在我们需要用到的页面加载模块

var check = require('./check_commonjs');

check()

CommonJS是用在Node应用中的模块规范,在做web开发中并不被前端开发人员所追逐,由于Node作为服务端应用,加载一个文件,速度就是真的是可以忽略不计的,然而浏览器作为一个客户端,在这个大框框下面,想要加载完一个js文件,再执行下面的js语句,加载时间速度真没那么快,所以就有了我们常用的AMD和CMD

AMD

随着RequireJS成为最流行的实现方式,异步模块规范(AMD)在前端界已经被广泛认同。

RequireJS的例子:

// 先创建一个 check_amd.js 的文件

define(['check'], function(){
    var flag = true;
    function check(){
        return flag;
    }

    return {
        check: check
    };
});

// 在我们需要用到的页面加载模块

require(['check_amd'], function (check){
    if(check.check()){
        console.log("哈哈哈");
    }
});

从代码的整洁性和可读性来讲, CommonJS 要好很多, 但AMD定义下的RequireJS 解决了上述同步加载文件导致的问题

CMD

CMD 通用模块定义最常见的应用例子就是SeaJS, 有些人把RequireJS 与 SeaJS做比较的时候, 会简单的认为异步与同步的区别
这是不太对, web端加载文件的时候一定是异步的

// 先创建一个 check_cmd.js 的文件

define(function(require, exports, module) {
    var a = require('a');//这里就不举例再创建a文件了
    function check(){
       return a.flag;
    }
    exports.check = check;
});

// 在我们需要用到的页面加载模块
seajs.use(['check_cmd.js'], function(check){
    if(check.check()){
        console.log("哈哈哈");
    }
});

CMD与AMD比较可以发现,AMD用户体验好由于没有延迟,依赖模块提前执行了,CMD性能好,因为只有用户需要的时候才执行。

在我们使用过程中,发现其实RequireJS和Sea.js在资源加载的时间点都是一样的,所以论“懒”的程度都是一样的。差别仅仅在于加载的脚本什么时候执行。RequireJS的依赖模块在回调函数执行前执行完毕,而Sea.js的依赖模块在回调函数执行require时执行。

ps: Sea.js原理
1.seajs中通过回调函数的Function.toString函数(真实使用parseDependencies(factory.toString())),使用正则表达式来捕捉内部的require字段,找到require('xx')内部依赖的模块xx
2.根据配置文件,找到jquery的js文件的实际路径
3.在dom中插入script标签,载入模块指定的js,绑定加载完成的事件,使得加载完成后将js文件绑定到require模块指定的id(这里就是jquery这个字符串)上回调函数内部依赖的js全部加载(暂不调用)完后,调用回调函数

兼容AMD、CMD、CommonJS,同时还支持老式的“全局”变量规范:

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        define([], factory);
    } else if (typeof define === 'function' && define.cmd) {
        define(function(require, exports, module){
            module.exports = factory()
        });
    } else if (typeof exports === 'object') {
        module.exports = factory();
    } else {
        root.LocalStorage = factory();
    }
}(this, function () {
    //    方法
    function myFunc(){};
 
 	myFunc.prototype = {
 		constructor: "myFunc"
 	}

    //    暴露公共方法
    return myFunc;	
})

CommonJS规范
seajs
requirejs
LABjs、RequireJS、SeaJS 哪个最好用?为什么?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant