js模块化规约

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/itsoftchenfei/article/details/77942338

随着前端技术的发展,先后也涌现出了很多模块化技术方案,本人将分享业界js模块化规约

目录

1.1.  CommonJS规范

1.2.  AMD规范

1.3.  CMD规范

1.4.  AMD& CMD

1.5.  ES6 module


1.1.  CommonJS规范

2009年,美国程序员RyanDahl创造了node.js项目,将javascript语言用于服务器端编程。这标志"Javascript模块化编程"正式诞生。老实说,在浏览器环境下,没有模块也不是特别大的问题,毕竟网页程序的复杂性有限;但是在服务器端,一定要有模块,与操作系统和其他应用程序互动,否则根本没法编程。

服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过require 方法来同步加载所要依赖的其他模块.

l  require 用来引入外部模块

l  exports 用于导出当前模块的方法或变量, 对外提供接口

l  module module对象代表模块本身

// someModule.js
exports.doSomething=function() {
    return"foo";
};
//otherModule.js
var someModule=require('someModule'); // in the vein of node
exports.doSomethingElse=function() {
    returnsomeModule.doSomething() +"bar";
};

优点:

  •  服务器端模块便于重用
  • NPM 中已经有将近20万个可以使用模块包
  •  简单并容易使用

缺点:

  • 同步的模块加载方式不适合在浏览器环境中(致力于前端),同步意味着阻塞加载,浏览器资源是异步加载的
  • 不能非阻塞的并行加载多个模块

实现:

  •  服务器端的 Node.js
  • Browserify,浏览器端的 CommonJS 实现,可以使用 NPM 的模块,但是编译打包后的文件体积可能很大
  • modules-webmake,类似Browserify,还不如 Browserify 灵活wreq,Browserify 的前身

1.2.  AMD规范

AsynchronousModule Definition 规范其实只有一个主要函数 define(id?, dependencies?, factory),有一个公有属性 define.amd,它要在声明模块的时候指定所有的依赖 dependencies,并且还要当做形参传到 factory 中,对于依赖的模块提前执行,依赖前置。

优点:

  • 适合在浏览器环境中异步加载模块(致力于前端)
  • 可以并行加载多个模块

缺点:

  •  提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅
  • 不符合通用的模块化思维方式,是一种妥协的实现

实现:

AMD规范中的require函数与一般的 CommonJS中的 require 不同。由于动态检测依赖关系使加载异步,对于基于回调的 require 需求强烈。

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

define({
    add:function(x, y) {
        return x+y;
    }
});

1.3.  CMD规范

Common ModuleDefinition 规范和 AMD 很相似,尽量保持简单,并与 CommonJS 和 Node.js 的 Modules 规范保持了很大的兼容性,函数有一个公有属性 define.cmd,CMD 模块中有两种方式提供对外的接口,一种是 exports.MyModule = ...,一种是使用 return 进行返回。

define(function(require, exports, module) {
    var $=require('jquery');
    var Spinning=require('./spinning');
    exports.doSomething= ...
    module.exports= ...
})

优点:

  • 依赖就近,延迟执行
  • 可以很容易在Node.js 中运行

缺点:

  •  依赖 SPM 打包,模块的加载逻辑偏重

实现:

  • Sea.js
  • coolie

1.4.  AMD& CMD

l  CMD和AMD都是CommonJS的一种规范的实现定义,RequireJS和SeaJS是对应的实践;

l  二者都是异步模块定义(AsynchronuousModule Definition)的一个实现;

l  CMD和AMD的区别:CMD相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而AMD则相反,定义模块的时候需要制定依赖模块,并以形参的方式引入factory中。

//AMD方式定义模块
define(['dep1','dep2'],function(dep1,dep2){
     //内部只能使用制定的模块
      return function(){};
});

//CMD
define(function(require,exports,module){
   //此处如果需要某XX模块,可以引入
   var xx=require('XX');
})

CMD允许异步加载,写法:

require.ensure(["module-a", "module-b"], function(require) {

    vara=require("module-a");

    // ...

});

Note:require.ensure only loads the modules, it doesn’t evaluate them.

注意:只下载,不执行.

AMD写法,与requireJS一致:

require(["module-a", "module-b"], function(a, b) {

    // ...

});

Note:AMD require loads and evaluate the modules. In webpack modules are evaluatedleft to right.

注意:与CMD不一样,AMD会下载并执行,执行顺序从左到右

Note:It’s allowed to omit the callback.

注意:并且允许省略回调

无论是AMD与CMD,文件组织方式与模块之间的逻辑都是一样的

1.5.  ES6 module

EcmaScript6 标准增加了JavaScript 语言层面的模块体系定义。ES6 模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。

优点:

  • 容易进行静态分析
  •  面向未来的EcmaScript 标准

缺点:

  • 原生浏览器端还没有实现该标准
  • 全新的命令字,新版的Node.js才支持

实现:

  • Babel

猜你喜欢

转载自blog.csdn.net/itsoftchenfei/article/details/77942338