《NodeJS開發(fā)教程4-模塊機(jī)制》

談到NodeJS的模塊機(jī)制湿弦,這還得從JavaScript這門語言說起庙楚。JavaScript語言可謂是編程中比較資深的一種語言了莲趣。從上個世紀(jì)(對就是上個世紀(jì))就開始流行了样悟,起初只是作為一些靜態(tài)網(wǎng)頁的簡單控制腳本和特效腳本而存在,而且書寫規(guī)范也沒有標(biāo)準(zhǔn)的官方定義攘滩,<script>標(biāo)簽引入JavaScript代碼帅刊,零零散散的整個網(wǎng)站應(yīng)用到處都是它的蹤跡,這種書寫方式對于一些小型的簡單web應(yīng)用還能夠勝任轰驳,但是隨著技術(shù)的發(fā)展,出現(xiàn)了像jquery,easyui等這樣的封裝庫,大大提升了開發(fā)效率级解,但是畢竟還是一些封裝庫冒黑,對于后期出現(xiàn)的前端工程化應(yīng)用卻只能作為工程支持庫的冰山一角,這時候Javascript模塊機(jī)制就應(yīng)運(yùn)而生了勤哗。首先要講的就是CommonJS規(guī)范抡爹,它是一種標(biāo)準(zhǔn),也是NodeJS常用的一種模塊書寫規(guī)范芒划。

模塊是Node.js 應(yīng)用程序的基本組成部分冬竟,文件和模塊是一一對應(yīng)的。換言之民逼,一個 Node.js 文件就是一個模塊泵殴,這個文件可能是JavaScript 代碼、JSON 或者編譯過的C/C++ 擴(kuò)展拼苍。

CommonJS模塊規(guī)范

CommonJS規(guī)范的提出主要是為了彌補(bǔ)JavaScript沒有標(biāo)準(zhǔn)的缺陷笑诅,以達(dá)到像Java,C#,Python等具備開發(fā)大型應(yīng)用的基礎(chǔ)能力。我們可以像Java那樣一個文件定義一個類(模塊)疮鲫,工程里進(jìn)行相互引用吆你。有了這項能力,我們就可以用NodeJS開發(fā)以下應(yīng)用:

  • 命令行工具
  • 服務(wù)器端JavaScript應(yīng)用程序
  • 桌面圖形應(yīng)用程序(后面會專門去講NodeJS圖形應(yīng)用開發(fā))
    CommonJS規(guī)范規(guī)范主要包括:1.模塊引用 2.模塊定義3.模塊標(biāo)識三個部分俊犯。
    1.模塊引用
    模塊通過require()進(jìn)行引用妇多,示例:
var http=require("http");//引入http模塊

2.模塊定義
上面我們引入的是官方定義的http模塊,當(dāng)然我們也可以引入我們自定義的模塊燕侠,首先我們需要通過exports定義者祖,如下:
新建 lession_exports.js 代碼如下:

/*模塊接口方法定義(導(dǎo)出)*/
exports.add=function(a,b)
{
    return a+b;
};

接著新建 lession_require.js 進(jìn)行引入我們剛剛自定義的模塊(模塊中含有一個add方法)

/*模塊機(jī)制*/
var modules_define=require("./lession_exports");//require("./lession_exports.js")這樣引入也可以
var result=modules_define.add(15,16);
console.log("調(diào)用模塊add方法,結(jié)果:"+result);
------------------------
運(yùn)行輸出結(jié)果:
   調(diào)用模塊add方法贬循,結(jié)果:31

剛剛我們定義并導(dǎo)出了一個方法咸包,那可能你會問了:我想導(dǎo)出一個類(或?qū)ο?該怎么辦?接下來我們就來講一下怎么導(dǎo)出一個對象的方法杖虾。
新建 lession_modules_exports.js 代碼如下:

/*模塊接口方法定義(導(dǎo)出)*/
//定義一個類
function People(name)
{
    this.name=name;
    this.sleep=function()
    {
        console.log(this.name+" 睡覺了");
    };
    this.speak=function()
    {
        console.log(this.name+" 說話了");
    };
}

module.exports=People;//導(dǎo)出

在我們前面創(chuàng)建的 lession_require.js 文件中添加代碼:

var People=require("./lession_modules_exports.js");//引入定義的類
var people=new People("Codingyu");//實例化一個類對象people
people.sleep();//調(diào)用people實例對象的sleep方法
people.speak();//調(diào)用people實例對象的speak方法

---------------------
執(zhí)行__ node lession_require.js __烂瘫,輸出結(jié)果如下:
  Codingyu 睡覺了
  Codingyu 說話了

以上是NodeJS模塊機(jī)制CommonJS規(guī)范的基本使用。接下來我們再談一下AMD規(guī)范和CMD規(guī)范以及怎么編寫前后端兼容的模塊奇适。

AMD模塊規(guī)范

之前我們講NodeJS前后端通吃坟比,既可以做前端又可以做后端服務(wù)器,那這樣我們在開發(fā)中就可以前后端有些模塊功能共享代碼嚷往,加快開發(fā)進(jìn)度葛账。但是如果前后端都使用CommonJS規(guī)范,會有一個問題皮仁,CommonJS規(guī)范require加載模塊是同步的籍琳,在服務(wù)器端調(diào)用直接讀取磁盤是瞬間的極快的菲宴,對于加載速度沒有任何影響,但是對于前端來說趋急,由于前端是通過網(wǎng)絡(luò)加載的喝峦,所以會產(chǎn)生require速度問題。AMD模塊規(guī)范對于模塊的引入是異步的呜达,所以比較適合前端的模塊管理谣蠢。接下來我們就來舉個栗子,但是在舉栗子之前我們需要先簡單掌握一下node里的一個很強(qiáng)大的包管理功能----NPM(我在這一章節(jié)會仔細(xì)去講解npm包管理http://www.reibang.com/p/445d0168d691

在NodeJS中使用AMD模塊規(guī)范和后面要講的CMD模塊規(guī)范,需要使用npm去下載 ‘a(chǎn)mdefine’:

npm install amdefine

amdefine安裝完畢后查近,接下來我們
新建 lession_exports_amd.js 代碼如下:

/*AMD模塊定義導(dǎo)出*/
//首先需要在文件中引入amdefine模塊
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
//定義自己的模塊
define(function()
{
    var exports={};
    exports.add=function(a,b)
    {
        return a+b;
    };
    return exports;//導(dǎo)出對象
});

接著新建 lession_require_amd.js 去測試一下,代碼如下:

/*AMD模塊機(jī)制*/
//首先需要在文件中引入amdefine模塊
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
//定義自己的模塊
//方法原型:define(["dep1","dep2"],function(dep1,dep2){});
define(["./lession_exports_amd"],function(exportAMD)
{
    var result=exportAMD.add(15,16);//調(diào)用另一個使用AMD規(guī)范定義的模塊接口方法
    console.log("通過AMD規(guī)范調(diào)用接口add方法結(jié)果:"+result);
    return {};
});

OK!我們可以運(yùn)行一下lession_require_amd.js眉踱,測試一下AMD模塊規(guī)范的使用,結(jié)果輸出:

通過AMD規(guī)范調(diào)用接口add方法結(jié)果:31

CMD模塊規(guī)范

CMD模塊規(guī)范其實是建立在AMD規(guī)范之上的霜威,是由國內(nèi)的玉伯提出谈喳,與AMD規(guī)范主要區(qū)別在于定義模塊和依賴引入的部分:

define(function(require,exports,module)
{
   ......
});

require,exports,module通過形參的方式傳遞給模塊,在需要依賴引入時侥祭,隨時調(diào)用require("xxx")叁执,和CommonJS很像。
再舉個栗子矮冬,新建 lession_exports_cmd.js 谈宛,代碼如下:

/*CMD模塊定義導(dǎo)出*/
//首先需要在文件中引入amdefine模塊
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
//定義自己的模塊
define(function(require,exports,module)
{
    var my={};
    my.add=function(a,b)
    {
        return a+b;
    };
    module.exports=my;
});

接著新建 lession_require_cmd.js 去測試一下CMD規(guī)范,代碼如下:

/*CMD模塊機(jī)制*/
//首先需要在文件中引入amdefine模塊
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
//定義自己的模塊
define(function(require,exports,module)
{
    var my=require("./lession_exports_cmd");
    var result=my.add(15,16);//調(diào)用另一個使用CMD規(guī)范定義的模塊接口方法
    console.log("通過CMD規(guī)范調(diào)用接口add方法結(jié)果:"+result);
});

執(zhí)行l(wèi)ession_require_cmd.js,結(jié)果輸出:

通過CMD規(guī)范調(diào)用接口add方法結(jié)果:31

AMD胎署、CMD吆录、CommonJS不同的規(guī)范,前端說:我們使用AMD/CMD,后端說:我們使用CommonJS琼牧,剛剛我們講恢筝,有一些前后端通用的模塊代碼,那我們能做到前后端模塊規(guī)范兼容統(tǒng)一嗎巨坊?答案是肯定的撬槽,舉個栗子
新建 lession_exports_compat.js 代碼如下:

/*兼容模式模塊定義導(dǎo)出*/
//定義自己的模塊
(function(name,definition)
{
    var hasDefine=typeof define==="function";//是否有define的定義
    var hasExports=typeof module!=="undefined"&&module.exports;//是否有module和exports的定義
    if(hasDefine)
    {
        //AMD或者CMD環(huán)境
        define(definition);
    }else if(hasExports)
    {
        //CommonJS規(guī)范(普通node模塊)
        module.exports=definition();
    }else{
        //普通window環(huán)境將模塊直接掛載到window對象上
        this[name]=definition();
    }
})('my',function () {
    //真正定義模塊內(nèi)容的地方
    var my={};
    my.add=function(a,b)
    {
        return a+b;
    };
    return my;
});

接下來再創(chuàng)建測試文件 lession_require_compat.js,代碼如下:

/*兼容模式模塊定義導(dǎo)出*/
//首先需要在文件中引入amdefine模塊----兼容模式測試可以不引入直接使用CommonJS規(guī)范
// if (typeof define !== 'function') {
//     var define = require('amdefine')(module);
// }
//定義自己的模塊
(function(name,definition)
{
    var hasDefine=typeof define==="function";//是否有define的定義
    var hasExports=typeof module!=="undefined"&&module.exports;//是否有module和exports的定義
    if(hasDefine)
    {
        //AMD或者CMD環(huán)境
        define(definition);
    }else if(hasExports)
    {
        //CommonJS規(guī)范(普通node模塊)
        module.exports=definition();
    }else{
        //普通window環(huán)境將模塊直接掛載到window對象上
        this[name]=definition();
    }
})('myrequire',function () {
    //正在引入模塊使用的地方
    var my=require("./lession_exports_compat");
    var result=my.add(15,16);
    console.log(result);
    return {};
});

很簡單吧趾撵!大體結(jié)構(gòu)就是一個自執(zhí)行函數(shù)侄柔,上面我代碼里注掉的地方,打開它便會產(chǎn)生AMD/CMD環(huán)境占调,注釋它則會默認(rèn)產(chǎn)生CommonJS環(huán)境暂题,這樣定義的模塊我們前后端就可以隨意copy過來使用了(當(dāng)然還有一些前后端不同API環(huán)境的影響)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末究珊,一起剝皮案震驚了整個濱河市薪者,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌剿涮,老刑警劉巖言津,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攻人,死亡現(xiàn)場離奇詭異,居然都是意外死亡悬槽,警方通過查閱死者的電腦和手機(jī)贝椿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來陷谱,“玉大人,你說我怎么就攤上這事瑟蜈⊙萄罚” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵铺根,是天一觀的道長宪躯。 經(jīng)常有香客問我,道長位迂,這世上最難降的妖魔是什么访雪? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮掂林,結(jié)果婚禮上臣缀,老公的妹妹穿的比我還像新娘。我一直安慰自己泻帮,他們只是感情好精置,可當(dāng)我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锣杂,像睡著了一般脂倦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上元莫,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天赖阻,我揣著相機(jī)與錄音,去河邊找鬼踱蠢。 笑死火欧,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的朽基。 我是一名探鬼主播布隔,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼稼虎!你這毒婦竟也來了衅檀?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤霎俩,失蹤者是張志新(化名)和其女友劉穎哀军,沒想到半個月后沉眶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡杉适,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年谎倔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猿推。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡片习,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蹬叭,到底是詐尸還是另有隱情藕咏,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布秽五,位于F島的核電站孽查,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坦喘。R本人自食惡果不足惜盲再,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓣铣。 院中可真熱鬧答朋,春花似錦、人聲如沸棠笑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腐晾。三九已至叉弦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間藻糖,已是汗流浹背淹冰。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留巨柒,地道東北人樱拴。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像洋满,于是被迫代替她去往敵國和親晶乔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 js是從網(wǎng)頁小腳本演變過來的牺勾,至今正罢,前端的js庫,也不像一個真正的模塊驻民。前端js經(jīng)歷了工具類庫翻具、組件庫履怯、前端...
    白昔月閱讀 3,283評論 2 11
  • 1 Node.js模塊的實現(xiàn) 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對于Node.js的模塊機(jī)制大都著...
    zlx_2017閱讀 1,243評論 0 1
  • 1 Node.js模塊的實現(xiàn)# 之前在網(wǎng)上查閱了許多介紹Node.js的文章,可惜對于Node.js的模塊機(jī)制大都...
    七寸知架構(gòu)閱讀 2,062評論 1 50
  • 模塊通常是指編程語言所提供的代碼組織機(jī)制,利用此機(jī)制可將程序拆解為獨立且通用的代碼單元裆泳。所謂模塊化主要是解決代碼分...
    MapleLeafFall閱讀 1,170評論 0 0
  • Node.js是目前非程局蓿火熱的技術(shù),但是它的誕生經(jīng)歷卻很奇特工禾。 眾所周知运提,在Netscape設(shè)計出JavaScri...
    w_zhuan閱讀 3,615評論 2 41