试想一下,如果一个网页有很多的js文件,那么浏览器在下载该页面的时候会先加载js文件,从而停止了网页的渲染,如果文件越多,浏览器可能失去响应。其次,要保证js文件的依赖性,依赖性最大的模块(文件)要放在最后加载,当依赖关系很复杂的时候,代码的编写和维护都会变得困难。
RequireJS就是为了解决这两个问题而诞生的:
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。
AMD和CMD
CMD(Common Module Definition) 通用模块定义。该规范明确了模块的基本书写格式和基本交互规则。该规范是在国内发展出来的。AMD是依赖关系前置,CMD是按需加载。
在 CMD 规范中,一个模块就是一个文件。代码的书写格式如下:
define(factory);
factory 为函数时,表示是模块的构造方法。执行该构造方法,可以得到模块向外提供的接口。factory 方法在执行时,默认会传入三个参数:require、exports 和 module:
define(function(require, exports, module) { // 模块代码 });
require是可以把其他模块导入进来的一个参数,而export是可以把模块内的一些属性和方法导出的。
CMD规范地址:https://github.com/seajs/seajs/issues/242
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。
对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。
AMD:提前执行(异步加载:依赖先执行)+延迟执行
CMD:延迟执行(运行到需加载,根据顺序执行)
CMD 推崇依赖就近,AMD 推崇依赖前置。看如下代码:
// CMD define(function(require, exports, module) { var a = require('./a') a.doSomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.doSomething() // ... }) // AMD 默认推荐的是 define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.doSomething() // 此处略去 100 行 b.doSomething() ... })
另外一个区别是:
AMD:API根据使用范围有区别,但使用同一个api接口
CMD:每个API的职责单一
AMD的优点是:异步并行加载,在AMD的规范下,同时异步加载是不会产生错误的。
CMD的机制则不同,这种加载方式会产生错误,如果能规范化模块内容形式,也可以
jquery1.7以上版本会自动模块化,支持AMD模式:主要是使用define函数,sea.js虽然是CommonJS规范,但却使用了define来定义模块
所以jQuery已经自动模块化了
seajs.config({ 'base':'https://www.jb51.net/', 'alias':{ 'jquery':'jquery.js'//定义jQuery文件 } });
define函数和AMD的define类似:
define(function(require, exports, module{ //先要载入jQuery的模块 var $ = require('jquery'); //然后将jQuery对象传给插件模块 require('./cookie')($); //开始使用 $.cookie方法 });
sea.js如何使用?
引入sea.js的库
如何变成模块?
define
3.如何调用模块?
-exports
-sea.js.use
4.如何依赖模块?
-require
<script type="text/javascript"> define(function (require,exports,module) { //exports : 对外的接口 //requires : 依赖的接口 require('./test.js');//如果地址是一个模块的话,那么require的返回值就是模块中的exports }) </script>
sea.js 开发实例
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>鼠标拖拽的模块化开发实践</title> <style type="text/css"> #div1{ width:200px; height:200px; background:black; position:absolute; display:none;} #div2{ width:30px; height:30px; background:yellow; position:absolute; bottom:0; right:0;} #div3{ width:100px; height:100px; background:blue; position:absolute; right:0; top:0;} </style> <script type="text/javascript" src="https://www.jb51.net/article/sea.js"></script> <script type="text/javascript"> //A同事 : seajs.use('./main.js'); </script> </head> <body> <input type="button" value="确定" /> <div> <div></div> </div> <div></div> </body> </html>
A同事