模块化是将一个总体系统按特定规则划分为各个独立的个体。好比计算机模块化为CPU、内存、电源、显示器等等。模块化是一个简化复杂的过程,同时在模块化后各个独立的个体之间的协调处理将变得更加的重要。用来协调处理各个模块之间的工做的部分称之为模块管理,监管和调配各个模块可以正常工做,并能处理意外错误。javascript
随着模块的数量增长,如何处理模块显得很是的重要,要保证各个模块之间的工做不会过度耦合、不会致使模块之间互相抵触,还要保证好各个模块之间的依赖关系。html
咱们熟悉的jquery插件就至关因而jquery的模块化,这些模块是挂载在系统主枝干上的,也就是说命名了一个模块a,那么就不能再命名一个模块a,不然的话会出现模块覆盖的问题。前端
为了解决这种问题,一种随时用随时取的模块思想诞生了,即便是在其余语言中存在好久,如c#的useing等,以及常被人们津津乐道的class类。在js中,客户端语言和服务器语言最大的区别就是,使用源代码必须从服务器上下载下来,而后才能解释运行。由于种种网络缘由,并不能保证模块可以正常的加载进来,如何加载模块又能够分红两类。java
在js业界,模块的加载分为AMD、CMD两类,它们都有本身的适合场合,尤为是在服务端和客户端之间。node
AMD、CMD的使用场合没有硬性规定,各取所需,合适的就是最好的。jquery
在模块规范上,就有着本质的区别,所以模块化的过程也是不一样的。git
如:github
// AMD // 定义 module1 ,依赖 depend1 和 depend2 define("module1", [" depend1", "depend2"], function (depend1, depend2) { // depend1 // depend2 }); // 定义 module2 ,依赖 module1 define("module2", ["module1"], function (module1) { // module1 }); // CMD // 定义模块为文件名 define(function (require, exports, module) { // require // exports // module });
AMD和CMD的模块定义很是的相似,都使用了define函数。不一样的是,AMD模块规范,在定义模块的时候就既定了依赖模块,而CMD模块并未这么作,模块之间的依赖关系有额外的配置文件决定。npm
在前端JS框架中,遵循AMD的有requireJS,遵循CMD的有seajs,各具特点。json
nodejs中的模块化遵循CMD,但又有些不一样。
// 新建一个计算圆周长、圆面积的模块 var pi = Math.PI; // 计算周长 exports.perimeter = function (r) { return 2 * pi * r; } // 计算面积 exports.area = function (r) { return pi * r * r; }
如上,定义了一个计算圆周长、圆面积的模块,由于每个文件就是一个模块,就不须要写define函数了,直接写出口exports便可。exports出口能够是任何对象。如:
A、出口是字面量
// module.js // 模块出口是字面量 module.exports="I'm a module!"; // index.js // 调用模块 var md = require("./module.js"); md;
B、出口是对象
// module.js // 模块出口是对象 module.exports={ name:"yundanran", love:"ming" }; // index.js // 调用模块 var md = require("./module.js"); md.name; md.love;
C、出口是类
// module.js function Animal(type){ this.type=type; } Animal.prototype.say=function(){ return "Animal type is "+this.type; } // 出口是一个类 module.exports=Animal; // index.js // 模块调用 var Md = require("./module.js"); var md = new Md("people"); md.say();
D、出口是函数
// module.js exports.fn1 = function () { return "fn1"; } exports.fn2 = function () { return "fn2"; } // index.js var md = require("./module.js"); md.fn1(); md.fn2();
由多个模块文件组成的一个总体,称之为包(模块包、package),这些模块文件合做完成一个相对更大一点的功能,具备一些处理错误、异常的能力。在模块包(文件夹)中约定包含:
新建一个包module1,用来计算圆柱体的面积和体积。新建文件、文件夹以下:
lib/circle.js:
// 计算圆周长、面积的模块 var pi = Math.PI; module.exports = { perimeter: function (r) { return 2 * pi * r; }, area: function (r) { return pi * r * r; } };
lib/rect.js:
// 计算矩形面积模块 module.exports = function (w, h) { return w * h; }
lib/index.js:
// 计算圆柱面积、体积 // 引用 circle 模块 var circle = require("./circle.js"); // 引用 rect 模块 var rect = require("./rect.js"); exports.area = function (r, h) { return 2 * circle.area(r) + circle.perimeter(r) * h; } exports.volume = function (r, h) { return circle.area(r) * h; }
index.js:
module.exports=require("./lib"); // 至关于 module.exports=require("./lib/index.js");
而后,cd到该模块文件夹,执行如下命令(关于nmp后续再说):
npm init
命令板会要求输入模块包的各类信息,最后在该包文件夹下生成package.json文件(/node_modules/module1/package.json)。package.json文件包含了模块包的各类信息,其中name值就是引用包须要用的名称。例package.json:
{ "name": "module1", "version": "1.0.0", "description": "", "main": "index.js", "directories": { "doc": "doc", "test": "test" }, "scripts": { "test": "test" }, "author": "ydr.me", "license": "BSD-2-Clause" }
引用该模块包,在/app3/index.js:
// 引用系统的 http 模块 var http = require("http"); // 引用系统的 url 模块 var url = require("url"); // 引用系统的 querystring 模块 var qs = require("querystring"); // 引用自定义 module1 模块,名称即为 package.json 里的 name 值 var module1 = require("module1"); http.createServer(function (request, response) { var query=qs.parse(url.parse(request.url).query); var r = query.r; var h = query.h; if (r !== undefined && h !== undefined) { write(response, "<h1>计算圆柱的面积和体积</h1>\ <p>半径 => " + r + "</p>\ <p>高 => " + r + "</p>\ <p>面积 => " + module1.area(r,h) + "</p>\ <p>体积 => " + module1.volume(r,h) + "</p>"); } else { write(response, "<h1>计算圆柱的面积和体积</h1>\ <p>请输入圆柱的班级或高</p>"); } }).listen(2014); function write(response, text) { response.writeHead(200, { "content-type": "text/html" }); response.write(text); response.end(); }
打开localhost:2014便可看到效果。
A、直接使用模块名称
在nodejs中,引用一个模块(包)名称,遵循如下规范。如在/app3/index.js中引用test模块包
var test = require("test");
系统依次搜寻如下路径,直到找到为止:
若是是引用如下系统的核心模块也能够直接使用模块名称:
B、标明模块路径
./
=> 当前路径../
=> 上层路径/
=> 根路径如:
// 引用同级目录的test.js var test = require("./test.js"); // 引用上级目录的test.js var test = require("../test.js"); // 引用根级目录的test.js var test = require("/test.js");
https://github.com/amdjs/amdjs-api/wiki/AMD
https://github.com/cmdjs/specification/blob/master/draft/module.md