@为了更好的开展话题,首先需了解什么是前端模块化
其实模块化的诞生不难理解,我们知道因为随着网站逐渐的发展,嵌入网页的Javascript代码越来越庞大,而网页越来越像桌面程序,需要一个团队去分工协作,进行管理和测试等等,为了更好的管理网页的业务逻辑,产生了模块化编程的理念。
模块就是实现特定功能的相互独立的一组方法。
因为有了模块,我们能更好的管理网页的业务逻辑,以及按照自己的需求去使用各种模块,并且可以让每个开发者都能设计自己想要的模块以及去使用别人的模块代码。 @有了模块的概念,但为了让大家能方便的加载各种模块,因此需要一套编写模块的规范,而目前通行的Javascript的模板规范共有两种:CommonJS 和 AMD
CommonJS的历史渊源: nodejs项目的诞生,将javascript语言用于服务器编程。由于服务器端开发十分复杂,需要与OS以及其他应用程序互动,模块化的理念对服务器端开发是必需的。而nodejs的模块系统,就是参照CommonJS规范实现的
@因此我理解CommonJS即为服务器端模块的规范。 CommonJS的规范: 根据CommonJS规范,一个单独的文件就是一个模块。加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。下面就是一个简单的模块文件example.js
console.log("example.js");
exports.message = "hi";
exports.say = function (){
console.log("hello");
};
使用require方法,加载example.js. 这时变量example就对应模块中的exports对象
var example = require('./example.js');
CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作。AMD规范则是非同步加载模块,允许指定回调函数。由于Node.js主要用于服务器编程,模块文件一般都已经存在于本地硬盘,所以加载起来比较快,不用考虑非同步加载的方式,所以CommonJS规范比较适用。但是,如果是浏览器环境,要从服务器端加载模块,这时就必须采用非同步模式,因此浏览器端一般采用AMD规范。
@因此我理解AMD即为能在客户端环境,并且能兼容服务器端模块的一种模块规范。
AMD规范使用define方法定义模块,下面是一个例子:
define(['package/lib'], function(lib){
function foo(){
lib.log('hello world');
}
return{
foo: foo
};
});
Define第一个参数表达依赖的模块数组,第二个为加载完依赖的模块数组后,模块执行的函数
AMD的模块加载定义:跟CommonJS 一样,AMD也采用require()语句来加载模块,但是与CommonJS不同的是,它要求有两个参数:
require([module], callback);
第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。AMD形式,就是下面这样:
require(['package/moduleA'], function(moduleA){
moduleA.add(2, 3);
});
modleA.add()与moduleA模块加载不是同步的,十分适合浏览器的环境
AMD 运行时核心思想是「Early Executing」,也就是提前执行依赖 AMD 的这个特性有好有坏: 首先,尽早执行依赖可以尽早发现错误。上面的代码中,假如 a 模块中抛异常,那么 main.js 在调用 factory 方法之前一定会收到错误,factory 不会执行;如果按需执行依赖,结果是: 1、没有进入使用 a 模块的分支时,不会发生错误; 2、出错时,main.js 的 factory 方法很可能执行了一半。 另外,尽早执行依赖通常可以带来更好的用户体验,也容易产生浪费。例如模块 a 依赖了另外一个需要异步加载数据的模块 b,尽早执行 b 可以让等待时间更短,同时如果 b 最后没被用到,带宽和内存开销就浪费了;这种场景下,按需执行依赖可以避免浪费,但是带来更长的等待时间。 引用AMD的Javscript库: 目前,主要有两个Javascript库实现了AMD规范:require.js和curl.js
@根据诞生的时间,先有了Requirejs,然后再诞生了SeaJS。但其实requirejs 和 seajs其实都是模块加载器,只是遵循的模块规范不同,加载机制有所不同。
@在讲解之前,我先说明下模块加载器出现之前存在的两个问题:
由此可以看出模块加载器的作用,主要是为了解决两个问题: 实现js文件的异步加载,避免网页失去响应 管理模块之间的依赖性,便于代码的编写和维护
@异同摘录知乎大神的讲法,感觉比较具体和准确 相同之处: RequireJS 和 SeaJS 都是模块加载器,倡导的是一种模块化开发理念,核心价值是让 JavaScript的模块化开发变得更简单自然。 不同之处:
前端模块化的诞生,大大促进我们前端的发展。前端模块化是web前端需掌握的基础知识之一。
http://www.douban.com/note/283566440/