CommonJS, AMD, CMD是什么及区别--简单易懂有实例

柔情只为你懂 2022-04-04 16:22 457阅读 0赞

  CommonJS, AMD, CMD都是JS模块化的规范。

  CommonJS是服务器端js模块化的规范,NodeJS是这种规范的实现。

  AMD(异步模块定义)和CMD(通用模块定义)都是浏览器端js模块化的规范。RequireJS 遵循的是 AMD,SeaJS 遵循的是 CMD。

一、CommonJS

  根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。所以,定义一个模块就是写一个新的js文件,但是最后要将文件的内容exports出来。接下来我们看一下如何定义模块和加载模块。

复制代码

  1. //定义一个module.js文件
  2. var A = function() {
  3. console.log('我是定义的模块');
  4. }
  5. //导出这个模块
  6. //1.第一种返回方式 module.exports = A;
  7. //2.第二种返回方式 module.exports.test = A
  8. //3.第三种返回方式 exports.test = A;
  9. exports.test = A;
  10. //再写一个test.js文件,去调用刚才定义好的模块,这两个文件在同一个目录下
  11. var module = require("./module"); //加载这个模块
  12. //调用这个模块,不同的返回方式用不同的方式调用
  13. //1.第一种调用方式 module();
  14. //2.第二种调用方式 module.test();
  15. //3.第三种调用方式 module.test();
  16. module.test();
  17. //接下来我们去执行这个文件,前提是你本地要安装node.js,不多说了,自己百度安装。
  18. //首先打开cmd, cd到这两个文件所在的目录下,执行: node test.js
  19. node test.js
  20. //输出结果:我是定义的模块

复制代码

  当我们执行 node test.js 的时候,根据 var module = require(“./module”); 会加载同一目录下的module.js文件,并将这个文件的exports对象返回,赋值给module,所以我们调用 module.test(); 就相当于执行了module.js文件。

  以上就是CommonJS规范下的模块定义与加载的形式。

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

二、AMD(异步模块定义)

  AMD规范通过define方法去定义模块,通过require方法去加载模块。RequireJS实现了这种规范。

  AMD只有一个接口:define(id?,dependencies?,factory); 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中。要是没什么依赖,就定义简单的模块(或者叫独立的模块),下面我们看代码实现:

复制代码

  1. //编写一个module1.js文件
  2. //定义独立的模块
  3. define({
  4. methodA: function() {
  5. console.log('我是module1的methodA');
  6. },
  7. methodB: function() {
  8. console.log('我是module1的methodB');
  9. }
  10. });
  11. //编写一个module2.js文件
  12. //另一种定义独立模块的方式
  13. define(function () {
  14. return {
  15. methodA: function() {
  16. console.log('我是module2的methodA');
  17. },
  18. methodB: function() {
  19. console.log('我是module2的methodB');
  20. }
  21. };
  22. });
  23. //编写一个module3.js文件
  24. //定义非独立的模块(这个模块依赖其他模块)
  25. define(['module1', 'module2'], function(m1, m2) {
  26. return {
  27. methodC: function() {
  28. m1.methodA();
  29. m2.methodB();
  30. }
  31. };
  32. });
  33. //再定义一个main.js,去加载这些个模块
  34. require(['module3'], function(m3){
  35. m3.methodC();
  36. });
  37. //我们在一个html文件中去通过RequireJS加载这个main.js
  38. //等号右边的main指的main.js
  39. <script data-main="main" src="require.js"></script>
  40. //浏览器控制台输出结果
  41. 我是module1methodA
  42. 我是module2methodB

复制代码

  以上就是AMD规范的模块定义和加载的形式,ReauireJS实现了这种规范。所以我们的例子也借助RequireJS去实现。

三、CMD(通用模块定义)

  CMD是SeaJS 在推广过程中对模块定义的规范化产出。

  AMD和CMD的区别:

  1. 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible(尽可能的懒加载,也称为延迟加载,即在需要的时候才加载)。

  2. CMD 推崇依赖就近,AMD 推崇依赖前置。
  虽然 AMD 也支持 CMD 的写法,同时还支持将 require 作为依赖项传递,但 RequireJS 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。看代码:

复制代码

  1. // CMD
  2. define(function(require, exports, module) {
  3. var a = require('./a');
  4. a.doSomething();
  5. // 此处略去 100 行
  6. var b = require('./b'); // 依赖可以就近书写
  7. b.doSomething();
  8. // ...
  9. })
  10. // AMD 默认推荐的是
  11. define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好
  12. a.doSomething();
  13. // 此处略去 100 行
  14. b.doSomething();
  15. //...
  16. })

复制代码

  3. AMD 的 API 默认是一个当多个用,CMD 的 API 严格区分,推崇职责单一。比如 AMD 里,require 分全局 require 和局部 require,都叫 require。CMD 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。CMD 里,每个 API 都简单纯粹。

发表评论

表情:
评论列表 (有 0 条评论,457人围观)

还没有评论,来说两句吧...

相关阅读

    相关 CommonJSAMDCMD区别

    zccst转载  学得比较晕,再次看commonjs,amd, cmd时好像还是没完全弄清楚,今天再整理一下:  commonjs是用在服务器端的,同步的,如no

    相关 AMD-CMD-CommonJS

    AMD和CMD都是为了解决浏览器端模块化问题而产生的 > 1、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块  > 2、CMD推崇就近依赖,只有在用到某个模块的