--- title: JavaScript模块化:CMD publish: true --- ## CMD的基本语法 ### CMD的概念 **CMD**(Common Module Definition):同步模块定义。CMD专门用于浏览器端,模块的加载是同步的。模块在使用时才会加载执行。 [**CMD规范**]():是 **[SeaJS](http://seajs.org/)** 在推广过程中对模块化定义的规范化产出。 ### SeaJS SeaJS:一个基于CMD规范实现的模块化开发解决方案。 官网链接: - - 推荐学习链接: - - ### 暴露模块的方式 > 不管是定义没有依赖的模块,还是定义有依赖的模块,参数只有一个,那就是 function。 **定义没有依赖的模块**: ```javascript define(function (require, exports, module) { exports.xxx = value //暴露模块 module.exports = value }) ``` 参数只有一个,那就是 function。function 里有三个参数: **定义有依赖的模块**: ```javascript //定义有依赖的模块 define(function (require, exports, module) { //引入依赖的模块(同步的方式) var module2 = require('./module2') //引入依赖的模块(异步的方式) require.async('./module3', function (m3) { }) //暴露模块 exports.xxx = value }) ``` 上面的代码可以看到,在引入依赖的模块时,有两种引入的方式:同步和异步。 ### 引入模块的方式 ```javascript define(function (require) { var m1 = require('./module1') var m4 = require('./module4') m1.show() m4.show() }) ``` ## SeaJS的使用举例(自定义模块) ### 1、创建项目结构 在工程文件中新建如下目录: ``` js | libs | sea.js | modules | module1.js | module2.js | module3.js | module4.js | main.js //主模块 index.html ``` ### 2、下载SeaJS,并导入 - 官网: - GitHub: 在官网下载`sea.js`文件,然后将其拷贝到项目的`js/libs/`目录中。这样的话,就导入成功了。 ### 3、自定义模块 (1)module1.js: ```javascript //定义没有依赖的模块 define(function (require, exports, module) { let name = '我是 module1 中的内容'; function foo1() { return name; } //暴露模块 module.exports = { foo1 }; //暴露出去的是 foo1这个函数对象 }); ``` (2)module2.js: ```javascript //定义没有依赖的模块 define(function (require, exports, module) { let name = '我是 module2 中的内容'; function foo2() { console.log(name); } //暴露模块 module.exports = foo2; //可以理解成:exports就是 foo2 这个函数 }); ``` (3)module3.js: ```javascript //定义没有依赖的模块 define(function (require,exports,module) { let data = '我是 module3 中的内容'; function foo3() { console.log(data); } //暴露模块 exports.module3 = { foo3 }; //可以理解成:给 export 对象暴露了 module3 这个属性,这个属性里有foo3 这个函数。 }); ``` (4)module4.js: 这个模块依赖了 module2 和 module3。 ```javascript //定义有依赖的模块 define(function (require, exports, module) { let name = '我是 module4 中的内容'; //同步的方式引入 module2 let myModule2 = require('./module2'); myModule2(); //异步的方式引入 module3 require.async('./module3', function (myModule3) { myModule3.module3.foo3(); }); function foo4() { console.log(name); } exports.foo4 = foo4; }) ``` (5)main.js: - `module1.js`没有依赖其他的模块,它是独立的 - `module4.js`依赖了`module2`和`module3`。 因此,让`main.js`依赖`module1.js`和`module4`就够了。 main.js: ```javascript //主模块(主模块不需要导出) define(function (require) { //导入 module1 let module1 = require('./module1'); console.log(module1.foo1()); //执行foo1函数后,将返回值打印 //导入 module4 let module4 = require('./module4'); module4.foo4(); }); ``` (6)index.html: ```html Document ``` 打印结果: ![](http://img.smyhvae.com/20180412_1955.png) ## others ### SeaJS 的介绍 SeaJS:一个基于CMD规范实现的模块化开发解决方案。 作者:Alibaba 玉伯。 官网: GitHub: 现在官网变成了: 特性: - 简单友好的模块定义规范。 - 自然直观的代码组织方式。 ![](http://img.smyhvae.com/20180303_2107.png) ### RequireJS(AMD)、SeaJS(CDM)、CommonJS、ES6 的对比 1、RequireJS 和 AMD: ![](http://img.smyhvae.com/20180303_1653.png) 异步模块定义,特点是依赖前置。 2、SeaJS 和 CMD: 同步模块定义。 ```javascript // 所有模块都通过 define 来定义 define(function(require, exports, module) { //通过 require 引入依赖 var $ require(`jquery`); var Spinning = require(`./spinning`); }) ``` 3、CommonJS: ![](http://img.smyhvae.com/20180303_1701.png) 以上三个都是 ES5里面的规范。 4、ES6: ES6的特性:export/import ![](http://img.smyhvae.com/20180303_1704.png)