1. 为什么要使用模块化?
2. CMD、AMD、CommonJS 规范分别指什么?有哪些应用?
- CommonJS:第一个流行的模块化规范由服务器端的JavaScript应用带来,CommonJS 规范是由 NodeJS 发扬光大,这标志着 JavaScript 模块化编程正式登上舞台。
- CommonJS 规范包含以下内容
- 模块的标识应遵循的规则(书写规范)。
- 定义全局函数require,通过传入模块标识来引入其他模块,执行的结果即为别的模块暴漏出来的API。
- 如果被 require 函数引入的模块中也包含依赖,那么依次加载这些依赖。
- 如果引入模块失败,那么require函数应该报一个异常。
- 模块通过变量exports来向往暴漏API,exports只能是一个对象,暴漏的API须作为此对象的属性。。
- 示例应用如下:
// moduleA.js
module.exports = function( value ){
return value * 2;
}
// moduleB.js
var moduleA = require('./moduleA');
var result = moduleA(4);
- 上面的代码,require 是同步的。模块系统需要同步读取模块文件内容,并编译执行以得到模块的接口,但是这在浏览器端实现却会遇到很多问题。浏览器端,加载 JavaScript 最佳、最容易的方式是在 document 中插入script标签。但脚本标签天生异步,传统 CommonJS 模块在浏览器环境中无法正常加载。于是便需要用一套标准模板来封装模块定义。
- AMD:即 Asynchromous Module Defination,中文是异步模块定义的意思,他就是浏览器端模块化开发的规范。由于不是 JavaScript 原生支持,使用 AMD 规范进行页面开发需要用到对应的库函数,也就是大名鼎鼎
RequireJS。
- requireJS主要解决两个问题
- 多个 js 文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器
- js 加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长
- requireJS定义了一个函数 define,它是全局变量,用来定义模块
define(id?, dependencies?, factory);
- id:可选参数,用来定义模块的标识,如果没有提供该参数,脚本文件名(去掉拓展名)。
- dependencies:是一个当前模块依赖的模块名称数组.
- factory:工厂方法,模块初始化要执行的函数或对象。如果为函数,它应该只被执行一次。如果是对象,此对象应该为模块的输出值。
- 在页面上使用 require 函数加载模块
require([dependencies], function(){});
- 第一个参数是一个数组,表示所依赖的模块。
- 第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该函数,从而在回调函数内部就可以使用这些模块。
- 示例应用如下:
define('myModule', ['jquery'], function($) {
// $ 是 jquery 模块的输出
$('body').text('hello world');
});
// 使用
require(['myModule'], function(myModule) {})
- require()函数在加载依赖的函数的时候是异步加载的,这样浏览器不会失去响应,它指定的回调函数,只有前面的模块都加载成功后,才会运行,解决了依赖性的问题。
- CMD:即Common Module Definition,通过模块定义。AMD有个RequireJS,CMD有个浏览器实现的SeaJS,SeaJS要解决的问题和RequireJS一样,只不过在模块定义方式和模块加载(可以说运行、解析)时机上有所不同。
- Sea.js 推崇一个模块一个文件,遵循统一的写法
define(id?, deps?, factory)
- 一个文件一个模块,所以经常就用文件名作为模块id。
- CMD推崇依赖就近,所以一般不在define的参数中写依赖,在factory中写。
- factory有三个参数
function(require, exports, module)
- require是一个方法,接受模块标识作为唯一的参数,用来获取其他模块提供的接口。
- exports是一个对象,用来向外提供模块的接口。
- module是一个对象,上面存储了与当前模块相关联的属性和方法。
- 示例应用如下:
// 定义模块 myModule.js
define(function(require, exports, module) {
var $ = require('jquery.js')
$('div').addClass('active');
});
// 加载模块
seajs.use(['myModule.js'], function(my){});
- AMD与CMD区别
- AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块。
- CMD推崇就近依赖,只有在用到某个模块的时候再去require。
- AMD和CMD最大的区别是对依赖模块的执行时机处理不同,注意不是加载的时机或者方式不同。
- 很多人说 RequireJS 是异步加载模块,SeaJS 是同步加载模块,这么理解实际上是不准确的,其实加载模块都是异步的,只不过AMD依赖前置,js可以方便知道依赖模块是谁,立即加载,而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是很多人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到可以忽略
3. 使用 RequireJS 完成以下要求,包括如下功能:
1. 首屏大图为全屏轮播
2. 有回到顶部功能
3. 图片区使用瀑布流布局(图片高度不一),下部有加载更多按钮,点击加载更多会加载更多数据(数据在后端 mock)
4(可选). 使用 r.js 打包应用
网友评论