CommonJS是服務(wù)器端模塊的規(guī)范,Node.js采用了這個(gè)規(guī)范。
根據(jù)CommonJS規(guī)范,一個(gè)單獨(dú)的文件就是一個(gè)模塊。每一個(gè)模塊都是一個(gè)單獨(dú)的作用域,也就是說(shuō),在該模塊內(nèi)部定義的變量,無(wú)法被其他模塊讀取,除非定義為global對(duì)象的屬性。
global.warning = true;
上面代碼的waining變量,可以被所有模塊讀取。當(dāng)然,這樣做是不推薦,輸出模塊變量的最好方法是使用module.exports對(duì)象。
var i = 1;var max = 30;module.exports = function () { for (i -= 1; i++ < max; ) { console.log(i); } max *= 1.1;};
上面代碼通過(guò)module.exports對(duì)象,定義了一個(gè)函數(shù),該函數(shù)就是模塊外部與內(nèi)部通信的橋梁。
加載模塊使用require方法,該方法讀取一個(gè)文件并執(zhí)行,最后返回文件內(nèi)部的module.exports對(duì)象。假定有一個(gè)一個(gè)簡(jiǎn)單的模塊example.js。
// example.jsconsole.log("evaluating example.js");var invisible = function () { console.log("invisible");}exports.message = "hi";exports.say = function () { console.log(message);}
使用require方法,加載example.js。
// main.jsvar example = require('./example.js');
這時(shí),變量example就對(duì)應(yīng)模塊中的module.exports對(duì)象,于是就可以通過(guò)這個(gè)變量,使用example.js模塊提供的各個(gè)方法。
require方法默認(rèn)讀取js文件,所以可以省略js后綴名,所以上面的代碼往往寫成下面這樣。
var example = require('./example');
js文件名前面需要加上路徑,可以是相對(duì)路徑(相對(duì)于使用require方法的文件),也可以是絕對(duì)路徑。如果省略路徑,node.js會(huì)認(rèn)為,你要加載一個(gè)核心模塊,或者已經(jīng)安裝在本地 node_modules 目錄中的模塊。如果加載的是一個(gè)目錄,node.js會(huì)首先尋找該目錄中的 package.json 文件,加載該文件 main 屬性提到的模塊,否則就尋找該目錄下的 index.js 文件。
下面的例子是使用一行語(yǔ)句,定義一個(gè)最簡(jiǎn)單的模塊。
// addition.jsexports.do = function(a, b){ return a + b };
上面的語(yǔ)句定義了一個(gè)加法模塊,做法就是在exports對(duì)象上定義一個(gè)do方法,那就是供外部調(diào)用的方法。使用的時(shí)候,只要用require函數(shù)調(diào)用即可。
var add = require('./addition');add.do(1,2)// 3
再看一個(gè)復(fù)雜一點(diǎn)的例子。
// foobar.jsfunction foobar(){ this.foo = function(){ console.log('Hello foo'); } this.bar = function(){ console.log('Hello bar'); }} exports.foobar = foobar;
調(diào)用該模塊的方法如下:
var foobar = require('./foobar').foobar, test = new foobar(); test.bar(); // 'Hello bar'
有時(shí),不需要exports返回一個(gè)對(duì)象,只需要它返回一個(gè)函數(shù)。這時(shí),就要寫成module.exports。
module.exports = function () { console.log("hello world")}
CommonJS規(guī)范加載模塊是同步的,也就是說(shuō),只有加載完成,才能執(zhí)行后面的操作。AMD規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù)。由于Node.js主要用于服務(wù)器編程,模塊文件一般都已經(jīng)存在于本地硬盤,所以加載起來(lái)比較快,不用考慮非同步加載的方式,所以CommonJS規(guī)范比較適用。但是,如果是瀏覽器環(huán)境,要從服務(wù)器端加載模塊,這時(shí)就必須采用非同步模式,因此瀏覽器端一般采用AMD規(guī)范。
AMD規(guī)范使用define方法定義模塊,下面就是一個(gè)例子:
define(['package/lib'], function(lib){ function foo(){ lib.log('hello world!'); } return { foo: foo };});
AMD規(guī)范允許輸出的模塊兼容CommonJS規(guī)范,這時(shí)define方法需要寫成下面這樣:
define(function (require, exports, module){ var someModule = require("someModule"); var anotherModule = require("anotherModule"); someModule.doTehAwesome(); anotherModule.doMoarAwesome(); exports.asplode = function (){ someModule.doTehAwesome(); anotherModule.doMoarAwesome(); };});
聯(lián)系客服