從零學(xué)習(xí)node.js之模塊規(guī)范(一)
什么是Node.js?
很多初學(xué)者并沒有真正地理解Node.js到底是什么。nodejs.org網(wǎng)站中的描述也沒有多大幫助。
首先要清楚Node不是一個(gè)Web服務(wù)器,這十分重要。它本身并不能做任何事情。它無法像Apache那樣工作。如果你希望它成為一個(gè)HTTP服務(wù)器,你必須借助它內(nèi)置庫自己編寫。Node.js只是計(jì)算機(jī)上執(zhí)行代碼的另一種方式,它是一個(gè)簡(jiǎn)單的JavaScript Runtime.
模塊化
在講解CommonJS, AMD, CMD這些概念之前,我們首先倆了解下js的模塊化。模塊化,顧名思義,就是將項(xiàng)目按照功能或者其他邏輯進(jìn)行分解處理,每個(gè)部分只處理一個(gè)功能,進(jìn)行功能的解耦處理,方便以后的開發(fā)和維護(hù)。那么模塊化必須具有以下的能力,才能進(jìn)行模塊的拆分和組裝:
- 定義封裝的模塊;
- 定義新模塊對(duì)其他模塊的依賴;
- 可對(duì)其他模塊的引入支持;
那么就需要一套規(guī)范準(zhǔn)則來定義這些能力,于是就出現(xiàn)了CommonJS, AMD, CMD等。
1. CommonJS
CommonJS原先叫做ServerJS,是js在服務(wù)端的規(guī)范,node使用的就是這種規(guī)范。根據(jù)CommonJS規(guī)范,一個(gè)單獨(dú)的文件就是一個(gè)模塊,require用來加載一個(gè)模塊,exports用來向外部暴露該模塊里的方法或?qū)傩浴?br />
例如:
// hello.js
function say(username){
console.log( 'hello, '+username );
}
exports.say = say;
=============
// main.js
var person = require('./hello');
person.say('wenzi'); // hello, wenzi
person.say('師少兵'); // hello, 師少兵
person.say('NUC'); // hello, NUC
同時(shí),require語句可以寫在文件中的任何位置,只要使用之前引用之前即可,不一定要寫在文件的最前面。不過,為了代碼更易閱讀,能直觀地看到當(dāng)前引用了哪些模塊,最好是放在文件的最前面。
EXPORTS與MODULE.EXPORTS的區(qū)別
可能有人見過直接使用exports的,有的是使用module.exports的,這里稍微的講解下這兩者的區(qū)別。
先舉個(gè)簡(jiǎn)單的例子:
var a = {name:'wenzi'};
var b = a;
console.log(a); // {name: "wenzi"}
console.log(b); // {name: "wenzi"}
a和b輸出的結(jié)果是一樣的?,F(xiàn)在我改變下b中name的值:
b.name = 'shaobing';
console.log(a); // {name: "shaobing"}
console.log(b); // {name: "shaobing"}
a和b的輸出結(jié)果都發(fā)生了改變。我再對(duì)b進(jìn)行重新聲明:
var b = {name:'師少兵'};
console.log(a); // {name: "shaobing"}
console.log(b); // {name: "師少兵"}
這三個(gè)例子輸出了三種結(jié)果:
- 聲明a對(duì)象,并把a(bǔ)賦值給b,然后a和b輸出了相同的結(jié)果;
- 改變了b中的name,那么a中的name也跟著改變;
- 重新聲明了b對(duì)象,那么a中的name則沒有跟著b一起改變
解釋:a 是一個(gè)對(duì)象,b 是對(duì) a 的引用,即 a 和 b 指向同一塊內(nèi)存,所以1中的輸出是一樣的。當(dāng)對(duì) b 作修改時(shí),即 a 和 b 指向同一塊內(nèi)存地址的內(nèi)容發(fā)生了改變,a 也會(huì)體現(xiàn)出來,所以第2個(gè)例子輸出也一樣。當(dāng) b 被覆蓋時(shí),b 指向了一塊新的內(nèi)存,a 還是指向原來的內(nèi)存,所以最后輸出會(huì)不一樣。
那么此時(shí)就可以引出exports和module.exports了:
module.exports初始值為一個(gè)空對(duì)象 {}exports是指向的module.exports的引用require()返回的是module.exports而不是exports
如果module.exports發(fā)生了新指向,則exports無效;若module.exports沒有發(fā)生變化,則直接exports即可。
2. AMD與RequireJS
說到AMD,不得不說到RequireJS,AMD從CommonJS社區(qū)獨(dú)立出來,單獨(dú)成為了AMD社區(qū),AMD的流行,很大程度上也是依托了RequireJS作者的推廣。
AMD規(guī)范中,默認(rèn)推薦的模塊格式是:
// hello.js
// 將需要引入的模塊全部寫入到數(shù)組中,然后傳遞參數(shù)進(jìn)行調(diào)用
define(['a', 'b'], function(a, ,b){
// do something
return{
hello : function(username){
console.log( 'hello, '+username );
}
}
})
==========
// main.js
define(['./hello'], function(h){
h.hello('wenzi');
})
也就是說,在AMD中,模塊必須使用define定義,依賴通過函數(shù)參數(shù)傳進(jìn)來,這樣的一個(gè)好處就是所有的依賴都能一目了然。
3. CMD與seajs
CMD規(guī)范是國(guó)內(nèi)著名的玉伯大神提出來的,將就的就是就近依賴,什么時(shí)候用到,就在那個(gè)地方進(jìn)行require。SeaJS就是使用的CMD規(guī)范:
// hello.js
define(function(require, exports, module){
var a = require('a');
// do a
var b = require( 'b' );
// do b
module.exports.hello = hello; // 對(duì)外輸出hello
})
從這里也能看到AMD和CMD的區(qū)別:
- AMD通常需要一次性引入全部的依賴,然后通過參數(shù)傳遞;而CMD則需要時(shí)才引入
不過,AMD也支持CMD這樣的引入格式,但內(nèi)部還是按照AMD的邏輯進(jìn)行執(zhí)行。
4. 總結(jié)
這篇文章里介紹了下CommonJS, AMD, CMD規(guī)范的相關(guān)區(qū)別與聯(lián)系,這里再簡(jiǎn)要的總結(jié)下:
- CommonJS: 每個(gè)文件就是一個(gè)模塊,不用define進(jìn)行定義,node使用此規(guī)范;
- AMD: 使用define定義一個(gè)模塊,講究提前依賴;
- CMD: 使用define定義模塊,將就就近依賴
好了,以上就是這篇文章的全部?jī)?nèi)容了,接下來,我們就要開始正式進(jìn)行node的學(xué)習(xí)了。感興趣的朋友們請(qǐng)繼續(xù)關(guān)注腳本之家哦。
- node.js+Ajax實(shí)現(xiàn)獲取HTTP服務(wù)器返回?cái)?shù)據(jù)
- 使用nodejs、Python寫的一個(gè)簡(jiǎn)易HTTP靜態(tài)文件服務(wù)器
- Node.js實(shí)戰(zhàn) 建立簡(jiǎn)單的Web服務(wù)器
- 輕松創(chuàng)建nodejs服務(wù)器(1):一個(gè)簡(jiǎn)單nodejs服務(wù)器例子
- 拋棄Nginx使用nodejs做反向代理服務(wù)器
- 教你如何使用node.js制作代理服務(wù)器
- 輕松創(chuàng)建nodejs服務(wù)器(4):路由
- 輕松創(chuàng)建nodejs服務(wù)器(3):代碼模塊化
- Nodejs實(shí)現(xiàn)的一個(gè)靜態(tài)服務(wù)器實(shí)例
- 從零學(xué)習(xí)node.js之搭建http服務(wù)器(二)
相關(guān)文章
Express 配置HTML頁面訪問的實(shí)現(xiàn)
這篇文章主要介紹了Express 配置HTML頁面訪問的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
Node.js中Express框架使用axios同步請(qǐng)求(async+await)實(shí)現(xiàn)方法
這篇文章主要介紹了Node.js中Express框架使用axios同步請(qǐng)求(async+await)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了express框架使用異步交互axios模塊實(shí)現(xiàn)同步請(qǐng)求的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2023-04-04
node-gyp安裝vuetify編譯失敗gyp?ERR的問題及解決
這篇文章主要介紹了node-gyp安裝vuetify編譯失敗gyp?ERR的問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
Node.js?中使用fetch?按JSON格式發(fā)post請(qǐng)求的問題解析
最近在測(cè)試一個(gè)api,可以用curl命令直接訪問,指定header相關(guān)配置,request?body(JSON),成功后返回一個(gè)JSON,這篇文章主要介紹了Node.js?中使用fetch?按JSON格式發(fā)post請(qǐng)求,需要的朋友可以參考下2023-04-04
gulp加批處理(.bat)實(shí)現(xiàn)ng多應(yīng)用一鍵自動(dòng)化構(gòu)建
這篇文章主要給大家介紹了利用gulp加上批處理(.bat)實(shí)現(xiàn)ng多應(yīng)用一鍵自動(dòng)化構(gòu)建的相關(guān)資料,文中介紹的很詳細(xì),需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02
Nodejs express框架一個(gè)工程中同時(shí)使用ejs模版和jade模版
這篇文章主要介紹了Nodejs express框架一個(gè)工程中同時(shí)使用ejs模版和jade模版 的相關(guān)資料,需要的朋友可以參考下2015-12-12

