JavaScript模块化:CMD

CMD的基本语法

CMD的概念

CMD(Common Module Definition):同步模块定义。CMD专门用于浏览器端,模块的加载是同步的。模块在使用时才会加载执行。

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

SeaJS

SeaJS:一个基于CMD规范实现的模块化开发解决方案。

官网链接:

推荐学习链接:

暴露模块的方式

不管是定义没有依赖的模块,还是定义有依赖的模块,参数只有一个,那就是 function。

定义没有依赖的模块

  1. define(function (require, exports, module) {
  2. exports.xxx = value
  3. //暴露模块
  4. module.exports = value
  5. })

参数只有一个,那就是 function。function 里有三个参数:

定义有依赖的模块

  1. //定义有依赖的模块
  2. define(function (require, exports, module) {
  3. //引入依赖的模块(同步的方式)
  4. var module2 = require('./module2')
  5. //引入依赖的模块(异步的方式)
  6. require.async('./module3', function (m3) {
  7. })
  8. //暴露模块
  9. exports.xxx = value
  10. })

上面的代码可以看到,在引入依赖的模块时,有两种引入的方式:同步和异步。

引入模块的方式

  1. define(function (require) {
  2. var m1 = require('./module1')
  3. var m4 = require('./module4')
  4. m1.show()
  5. m4.show()
  6. })

SeaJS的使用举例(自定义模块)

1、创建项目结构

在工程文件中新建如下目录:

  1. js
  2. | libs
  3. | sea.js
  4. | modules
  5. | module1.js
  6. | module2.js
  7. | module3.js
  8. | module4.js
  9. | main.js //主模块
  10. index.html

2、下载SeaJS,并导入

在官网下载sea.js文件,然后将其拷贝到项目的js/libs/目录中。这样的话,就导入成功了。

3、自定义模块

(1)module1.js:

  1. //定义没有依赖的模块
  2. define(function (require, exports, module) {
  3. let name = '我是 module1 中的内容';
  4. function foo1() {
  5. return name;
  6. }
  7. //暴露模块
  8. module.exports = { foo1 }; //暴露出去的是 foo1这个函数对象
  9. });

(2)module2.js:

  1. //定义没有依赖的模块
  2. define(function (require, exports, module) {
  3. let name = '我是 module2 中的内容';
  4. function foo2() {
  5. console.log(name);
  6. }
  7. //暴露模块
  8. module.exports = foo2; //可以理解成:exports就是 foo2 这个函数
  9. });

(3)module3.js:

  1. //定义没有依赖的模块
  2. define(function (require,exports,module) {
  3. let data = '我是 module3 中的内容';
  4. function foo3() {
  5. console.log(data);
  6. }
  7. //暴露模块
  8. exports.module3 = { foo3 }; //可以理解成:给 export 对象暴露了 module3 这个属性,这个属性里有foo3 这个函数。
  9. });

(4)module4.js:

这个模块依赖了 module2 和 module3。

  1. //定义有依赖的模块
  2. define(function (require, exports, module) {
  3. let name = '我是 module4 中的内容';
  4. //同步的方式引入 module2
  5. let myModule2 = require('./module2');
  6. myModule2();
  7. //异步的方式引入 module3
  8. require.async('./module3', function (myModule3) {
  9. myModule3.module3.foo3();
  10. });
  11. function foo4() {
  12. console.log(name);
  13. }
  14. exports.foo4 = foo4;
  15. })

(5)main.js:

  • module1.js没有依赖其他的模块,它是独立的

  • module4.js依赖了module2module3

因此,让main.js依赖module1.jsmodule4就够了。

main.js:

  1. //主模块(主模块不需要导出)
  2. define(function (require) {
  3. //导入 module1
  4. let module1 = require('./module1');
  5. console.log(module1.foo1()); //执行foo1函数后,将返回值打印
  6. //导入 module4
  7. let module4 = require('./module4');
  8. module4.foo4();
  9. });

(6)index.html:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7. <title>Document</title>
  8. </head>
  9. <body>
  10. <!-- 引入 sea.js库 -->
  11. <script src="js/libs/sea.js"></script>
  12. <script>
  13. // 引入主模块
  14. seajs.use('./js/modules/main.js');
  15. </script>
  16. </body>
  17. </html>

打印结果:

JavaScript模块化:CMD - 图1

others

SeaJS 的介绍

SeaJS:一个基于CMD规范实现的模块化开发解决方案。

作者:Alibaba 玉伯。

官网:http://seajs.org/

GitHub:https://github.com/seajs/seajs

现在官网变成了:https://seajs.github.io/seajs/docs/

特性:

  • 简单友好的模块定义规范。

  • 自然直观的代码组织方式。

JavaScript模块化:CMD - 图2

RequireJS(AMD)、SeaJS(CDM)、CommonJS、ES6 的对比

1、RequireJS 和 AMD:

JavaScript模块化:CMD - 图3

异步模块定义,特点是依赖前置。

2、SeaJS 和 CMD:

同步模块定义。

  1. // 所有模块都通过 define 来定义
  2. define(function(require, exports, module) {
  3. //通过 require 引入依赖
  4. var $ require(`jquery`);
  5. var Spinning = require(`./spinning`);
  6. })

3、CommonJS:

JavaScript模块化:CMD - 图4

以上三个都是 ES5里面的规范。

4、ES6:

ES6的特性:export/import

JavaScript模块化:CMD - 图5