大行其道的模块化编程-CommonJS、AMD、CMD、UMD、ES6

1 篇文章 0 订阅
1 篇文章 0 订阅

一 何为模块化开发:

软件模块是一套一致而互相有紧密关连的软件组织

它分别包含了程序数据结构两部份。

模块的接口表达了由该模块提供的功能和调用它时所需的元素

模块是可能分开地被编写的单位。这使他们可再用和允许广泛人员同时协作、编写及 研究不同的模块

以上是百度百科对它的定义黑色字体已经很好的体现了模块化开发的特点,自行体会。


二 js 模块化开发实现方案:

CommonJS

CommonJS是服务器端模块的规范,Node.js采用了这个规范。

根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。

// foobar.js

//私有变量
var test = 123;

//公有方法
function foobar () {

    this.foo = function () {
        // do someing ...
    }
    this.bar = function () {
        //do someing ...
    }
}

//exports对象上的方法和变量是公有的
var foobar = new foobar();
exports.foobar = foobar;
//require方法默认读取js文件,所以可以省略js后缀
var test = require('./boobar').foobar;

test.bar();

CommonJS
加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了
AMD CMD 解决方案。


AMD和requireJS

AMDrequireJs 在推广过程中的规范化产出。

AMD是”Asynchronous Module Definition”的缩写,意思就是”异步模块定义”.

AMD设计出一个简洁的写模块API:

define(id?, dependencies?, factory);

第一个参数 id 为字符串类型,表示了模块标识,为可选参数。若不存在则模块标识

应该默认定义为在加载器中被请求脚本的标识。如果存在,那么模块标识必须为顶层

的或者一个绝对的标识。

第二个参数,dependencies ,是一个当前模块依赖的,已被模块定义的模块标识的数组字面量。

第三个参数,factory,是一个需要进行实例化的函数或者一个对象。

//定义有依赖的模块

define(["alpha"], function( alpha ){
    return {
        verb : function(){
            return alpha.verb() + 1 ;
        }
    }
});
//有名字的模块

define("alpha", [ "require", "exports", "beta" ], function( require, exports, beta ){
    export.verb = function(){
        return beta.verb();
        // or:
        return require("beta").verb();
    }
});

requireJS解决了两个问题
(1)实现js文件的异步加载,避免网页失去响应。   
(2)管理模块之间的依赖性,便于代码的编写和维护。


CMD和SeaJS

CMD是SeaJS 在推广过程中对模块定义的规范化产出
对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不同)。
CMD推崇依赖就近,AMD推崇依赖前置。

//AMD
define(['./a','./b'], function (a, b) {

    //依赖一开始就写好
    a.test();
    b.test();
});

//CMD
define(function (requie, exports, module) {

    //依赖可以就近书写
    var a = require('./a');
    a.test();

    ...
    //软依赖
    if (status) {

        var b = requie('./b');
        b.test();
    }
});

UMD

UMD是AMD和CommonJS的糅合

AMD模块以浏览器第一的原则发展,异步加载模块。
CommonJS模块以服务器第一原则发展,选择同步加载,它的模块无需包装(unwrapped modules)。
这迫使人们又想出另一个更通用的模式UMD (Universal Module Definition)。希望解决跨平台的解决方案。

UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。
在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

(function (window, factory) {
    if (typeof exports === 'object') {

        module.exports = factory();
    } else if (typeof define === 'function' && define.amd) {

        define(factory);
    } else {

        window.eventUtil = factory();
    }
})(this, function () {
    //module ...
});

ES6

ES6的模块化的基本规则或特点:

    1:每一个模块只加载一次, 每一个JS只执行一次, 如果下次再去加载同目录下同文件,直接从内存中读取。 一个模块就是一个单例,或者说就是一个对象;

    2:每一个模块内声明的变量都是局部变量, 不会污染全局作用域;

    3:模块内部的变量或者函数可以通过export导出;

    4:一个模块可以导入别的模块

//lib.js
//导出常量
export const sqrt = Math.sqrt;
//导出函数
export function square(x) {
    return x * x;
}
//导出函数
export function diag(x, y) {
    return sqrt(square(x) + square(y));
}

//main.js
import { square, diag } from './lib';
console.log(square(11)); // 121
console.log(diag(4, 3)); // 5

   
 babelJS:http://babeljs.io/
 Exploring ES6(Dr.Axel Rauschmayer):http://exploringjs.com/es6/ch_modules.html
 SeaJS和RequireJS的异同:https://github.com/seajs/seajs/issues/277
 SeaJS与RequireJS最大的区别:https://www.douban.com/note/283566440/
 阮老师es6#module:http://es6.ruanyifeng.com/#docs/module
 AMD和CMD的区别 https://www.zhihu.com/question/20351507/answer/14859415

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值