资讯专栏INFORMATION COLUMN

前端模块化进程,commonJS,AMD,CMD对比

firim / 2118人阅读

摘要:是另一种模块化方案,它与很类似,不同点在于推崇依赖前置提前执行,推崇依赖就近延迟执行。

commonJS规范

随着前端技术的不断发展,项目越来越大,越来越不好管理,多人开发越来让开发者头疼,于是出现了命名空间,这没有办法的办法,但是所有变量都是全局的话,管理非常混乱,而且在Node 出现前,javascript 在服务器端基本没有市场,经过javascript 不断努力,社区为 javascript 制定了相应的规范。其中 commonJS 规范的提出算是最为重要的里程碑。
commonJS对模块的引用非常简单,主要分为模块引用、模块定义和模块标示3部分

1.模块定义

在模块中,上下文提供了 require() 方法来引入外来模块,引入对应的功能。上下文还提供了 exports 对象,用来导出当前模块的方法或变量。上下文还提供了一个module对象,它代表模块本身,而 exports 是 module 的属性。在node中一个文件就是一个模块,将方法挂载在exports上作为属性即可定义导出方式。

// math.js
exports.add = function () {
    var sum = 0,
        i = 0,
        args = arguments,
        l = args.length;
    while (i < l) {
        sum += args[i];
        i++
    }
    return sum;
}
2.模块引用

在commonJS规范中,存在 require() 方法,这个方法接受模块标示,以此引入一个模块的API到当前的上下文中。
模块引入的实例代码

var math = require("math");
3.模块标示

模块标示其实就是传递给require()的参数,必须符合小驼峰命名的字符串,或者以.,..开头的相对路径,或者绝对路径。

commonJS 和 AMD

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,为什么这么说呢?
这需要分析一下浏览器端的js和服务器端js都主要做了哪些事,有什么不同了:

服务器端 浏览器js
加载时从磁盘中加载 加载时需要通过网络加载
相同的代码需要多次执行 代码需要从一个服务器端分发到多个客户端执行
CPU和内存资源是瓶颈 带宽是瓶颈

commonJS在服务器端运行完全没有问题的,因为所有资源都在服务器端的磁盘里,加载速度很快。但是在浏览器端因为网速的限制,加载资源需要时间,会阻塞代码的运行,而AMD(异步模块定义)的出现,可以异。它的模块定义如下:

define(id?, dependencies?, factory);

它的模块id和依赖都是可选的,而factory函数的内容就是实际代码内容,假设一个模块不依赖任何一个模块

//math.js
define(function () {
    var math = {};
    math.add = function (arr) {
        for(var i = 0, sum = 0; i < arr.length; i++) {
            sum += arr[i];
        }
        return sum;
    }
    math.muti = function (arr) {
        for(var i = 0, sum = 0; i < arr.length; i++) {
            sum *= arr[i];
        }
        return sum;
    }
})

引用的时候这样写

//main.js
define(["math", function(math) {
    var arr = [1, 10, 20],
        sum = math.add(arr);
    console.log(sum);   //31
}]

当然这是原理,大家明白了之后,对于入门者,估计还是不知道怎么去用,那么我就帮人帮到底(会用的绕过)。

引入一个requirejs

如果觉得觉得这个文件加载也会堵塞 js 的话就把他放在代码的底部,然后这样写

其中defer是为了兼容IE浏览器。加载完requirejs之后,怎么加载我们自己的js呢

2.加载我们自己的js

// main.js
// 首先用config()指定各模块路径和引用名
require.config({
  baseUrl: "js/lib",
  paths: {
    "jquery": "jquery.min",  //实际路径为js/lib/jquery.min.js
    "underscore": "underscore.min",
  }
});
// 执行基本操作
require(["jquery","underscore"],function($,_){
  // some code here
});

data-main 属性里面的就是我们自己的入口文件了,由于 requirejs 默认加载 js 文件的,所以 后缀 js 可以省略。OK,下面就可以快乐的写模块了。

CMD规范

CMD规范由国内的玉伯大神指出。是另一种js模块化方案,它与AMD很类似,不同点在于:AMD 推崇依赖前置、提前执行,CMD推崇依赖就近、延迟执行。

/** AMD写法 **/
define(["a", "b", "c", "d", "e", "f"], function(a, b, c, d, e, f) { 
     // 等于在最前面声明并初始化了要用到的所有模块
    a.doSomething();
    if (false) {
        // 即便没用到某个模块 b,但 b 还是提前执行了
        b.doSomething()
    } 
});

/** CMD写法 **/
define(function(require, exports, module) {
    var a = require("./a"); //在需要时申明
    a.doSomething();
    if (false) {
        var b = require("./b");
        b.doSomething();
    }
});

/** sea.js **/
// 定义模块 math.js
define(function(require, exports, module) {
    var $ = require("jquery.js");
    var add = function(a,b){
        return a+b;
    }
    exports.add = add;
});

require, exports 和 module 通过形参传递给模块,在需要依赖模块时,随时引入,可以看出,与 AMD 规范相比,CMD 规范更加接近 node 对 commonJS规范的定义。

兼容多种模块规范

技术在发展,优秀的开源项目也在不断更新,比如jquery,underscore。它们很快出了兼容不同规范的版本,那么他们是怎么做到的,是写好几套符合不同规范的代码么,当然不是。那么我们怎么写出像他们那样兼容不同规范的代码呢,很简单,我给出一个例子:

//hello.js
;(function(name, definition){
    //检测上下文环境是否为 AMD 或 CMD
    var hasDefine = typeof define === "function",
        hasExports = typeof module !== "undefined" && module.exports;
    if (hasDefine) {
        //AMD 环境或 CMD 环境
        define(definition);
    } else if (hasExports) {
        // 定义为普通的node模块
        module.exports = definition();
    } else {
        //将模块的执行结果挂在 window 变量中,在浏览器中 this 指向 window 对象
        this[name] = definition();
    }
})("hello", function() {
    //代码主体
    var hello = function () {};
    return hello;
})

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85037.html

相关文章

  • 前端块化规范笔记

    摘要:目前通行的的模板规范共有两种和的模块系统,是参照规范实现的即为服务器端模块的规范。规范则是非同步加载模块,允许指定回调函数。 目前通行的Javascript的模板规范共有两种:CommonJS 和 AMD commonjs nodejs的模块系统,是参照commonjs规范实现的 commonjs即为服务器端模块的规范。 commonjs的规范: 根据commonjs规范,一个单独的...

    honmaple 评论0 收藏0
  • CommonJS、ES2015、AMDCMD模块规范对比与介绍

    摘要:是服务器端模块化的规范,是这种规范的实现。异步模块定义和通用模块定义都是浏览器端模块化的规范。是在推广过程中对模块定义的规范化产出。 前言:最近看到这样一个问题「import ... from」、「 import ... = require()」 和 「import(path: string)」有什么区别? ,我遇到的项目中大都是ES6模块规范,其他规范也有,但为什么会有这些规范?具体...

    MSchumi 评论0 收藏0
  • 块化

    摘要:模块化总结最近重新复习的模块化的相关知识,总结一下,仅供自己理解和大家参考。模块化的优点可维护性根据定义,每个模块都是独立的。良好设计的模块会尽量与外部的代码撇清关系,以便于独立对其进行改进和维护。 模块化总结 最近重新复习的模块化的相关知识,总结一下,仅供自己理解和大家参考。 模块化的优点 可维护性:根据定义,每个模块都是独立的。良好设计的模块会尽量与外部的代码撇清关系,以便于独立...

    ?xiaoxiao, 评论0 收藏0
  • JS块化——CommonJS AMD CMD UMD ES6 Module 比较

    摘要:即尽早地执行依赖模块。阮一峰输出值的引用模块是动态关联模块中的值,输出的是值得引用。的加载实现阮一峰运行时加载静态编译模块是运行时加载,模块是编译时输出接口。 模块化开发 优点 模块化开发中,通常一个文件就是一个模块,有自己的作用域,只向外暴露特定的变量和函数,并且可以按需加载。 依赖自动加载,按需加载。 提高代码复用率,方便进行代码的管理,使得代码管理更加清晰、规范。 减少了命名冲...

    shadowbook 评论0 收藏0
  • 使用CommonJSAMD以及CMD编写块化JavaScripts

    摘要:模块化编程首先,我想说说模块化编程这个概念当我不清楚这个概念的时候,其实说什么模块化编程多好多好都是懵逼的而我一直不觉得有多好,其实也是因为我从开始写,就一直都在模块化编程啊我们写一个文件然后我们在文件中引入然后调用方法哈哈这样已经是模块化 模块化编程 首先,我想说说模块化编程这个概念当我不清楚这个概念的时候,其实说什么模块化编程多好多好都是懵逼的而我一直不觉得有多好,其实也是因为我从...

    nifhlheimr 评论0 收藏0

发表评论

0条评论

firim

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<