Nodejs的模塊化

CommonJS模塊規(guī)范

  • 一個(gè)js文件就是一個(gè)模塊
  • CommonJS 就是一套約定標(biāo)準(zhǔn)约炎,不是技術(shù); 用于約定我們的代碼應(yīng)該是怎樣的一種結(jié)構(gòu)蟹瘾。
  • Node 采用的模塊化結(jié)構(gòu)是按照 CommonJS 規(guī)范圾浅。
  • CommonJS的特點(diǎn):
    • 所有代碼都運(yùn)行在模塊作用域,不會(huì)污染全局作用域憾朴。
    • 模塊可以多次加載狸捕,但是只會(huì)在第一次加載時(shí)運(yùn)行一次,然后運(yùn)行結(jié)果就被緩存了众雷,以后再加載府寒,就直接讀取緩存結(jié)果。要想讓模塊再次運(yùn)行报腔,必須清除緩存株搔。
    • 模塊加載的順序,按照其在代碼中出現(xiàn)的順序纯蛾。
  • 模塊的分類
    • 自定義模塊:即我們自己寫的功能模塊文件纤房。
    • 核心模塊:即Node自帶的功能模塊,如:HTTP模塊翻诉,fs模塊等等炮姨。
    • 第三方模塊:社區(qū)或第三方開發(fā)好的功能模塊,可以直接拿回來(lái)用碰煌。
  • 模塊的導(dǎo)入
    • 通過(guò)require("fs")來(lái)加載模塊
    • 如果是第三方模塊舒岸,需要先使用npm進(jìn)行下載
    • 如果是自定義模塊,需要加上相對(duì)路徑./或者../,可以省略.js后綴芦圾,如果文件名是index.js那么index.js也可以省略
    • 模塊可以被多次加載蛾派,但是只會(huì)在第一次加載

module.exports與exports

  • 載入一個(gè)模塊就是構(gòu)建一個(gè) Module 實(shí)例,一個(gè)新的 JS 文件就是一個(gè)模塊
  • module.exports 是用于為模塊導(dǎo)出成員的接口个少。
  • 在模塊的內(nèi)部洪乍,module變量代表的就是當(dāng)前模塊,它的exports屬性就是對(duì)外的接口夜焦,加載某個(gè)模塊壳澳,加載的就是module.exports屬性,這個(gè)屬性指向一個(gè)空的對(duì)象茫经。
  • exports是指向module.exports的引用巷波,相當(dāng)于在模塊開始執(zhí)行的時(shí)候進(jìn)行var exports = module.exports操作萎津。從下面的打印中可以看出,它們最初都是一個(gè)空對(duì)象{}抹镊,而這兩個(gè)對(duì)象實(shí)際上指向同一塊內(nèi)存空間姜性,即在不改變它們指向的內(nèi)存地址的前提下,它們是等價(jià)的髓考。
console.log(exports) //{}
console.log(module) //Module {……exports: {},parent: null……}
console.log(exports === module.exports) //true
  • require引入的對(duì)象本質(zhì)上是module.exports部念,這也意味著module.exportsexports指向的不是同一塊內(nèi)存時(shí),exports的內(nèi)容就會(huì)失效氨菇。
//try.js
exports = {name: "Join"}

module.exports = {name: "Bob"}
//main.js
let name = require('./try.js')
console.log(name) //{ name: 'Bob' }

require加載文件規(guī)則

  • require('../file.js'); // 上級(jí)目錄下找 file.js 文件
    require('./file.js'); // 同級(jí)目錄找 file.js 文件
    require('file.js'); // 同級(jí)目錄找 file.js 文件
  • 加載順序:
    • 按js文件來(lái)執(zhí)行(先找對(duì)應(yīng)路徑當(dāng)中的module.js文件來(lái)加載)
    • 按json文件來(lái)解析(若上面的js文件找不到時(shí)儡炼,則找對(duì)應(yīng)路徑當(dāng)中的module.json文件來(lái)加載)
    • 按照預(yù)編譯好的c++模塊來(lái)執(zhí)行(尋找對(duì)應(yīng)路徑當(dāng)中的module.node文件來(lái)加載)
    • 若參數(shù)字符串為一個(gè)目錄(文件夾)的路徑,則自動(dòng)先查找該文件夾下的package.json文件查蓉,然后再再加載該文件當(dāng)中main字段所指定的入口文件乌询。(若package.json文件當(dāng)中沒有main字段,或者根本沒有package.json文件豌研,則再默認(rèn)查找該文件夾下的index.js文件作為模塊來(lái)載入妹田。)

CommonJS引入與ES6的區(qū)別

  • CommonJS是直接做一個(gè)值的拷貝操作,也就是一旦輸出一個(gè)值鹃共,模塊內(nèi)部的變化是影響不到這個(gè)值的
//try.js
let counter = 1

let addCounter = () => {
  counter++
}

module.exports = {
  counter,
  addCounter
}
//main.js
let func = require('./try.js')

console.log(func.counter) //1
func.addCounter()
console.log(func.counter) //1
  • ES6模塊是動(dòng)態(tài)引用鬼佣,并且不會(huì)緩存值,模塊里面的變量綁定其所在的模塊霜浴。
//try.js
export let counter = 1

export let addCounter = () => {
  counter++
}
//main.js
import {counter,addCounter} from './try.js'
console.log(counter) //1
addCounter()
console.log(counter) //2
  • CommonJS模塊的循環(huán)引用
    • 執(zhí)行node main.js->第一行晶衷,require(a.js)
    • 進(jìn)入require(a)方法:判斷緩存->無(wú)->初始化一個(gè)module->將module加入緩存->執(zhí)行a.js內(nèi)容
    • 第一行導(dǎo)出a=1->第二行引入b.js
    • 執(zhí)行b.js的內(nèi)容,第一行導(dǎo)出b=11,第二行require(a.js)
    • 此時(shí)a.js是第二次調(diào)用require阴孟,判斷緩存->有->繼續(xù)執(zhí)行b.js->第三行打印1->第四行修改b=22
    • b文件執(zhí)行完畢回到a.js中->第三行打印b=22->導(dǎo)出a=2
    • a文件執(zhí)行完畢晌纫,回到main.js中->獲取a,第二行輸出a=2->執(zhí)行完畢
// a.js
module.exports.a = 1;
var b = require('./b');
console.log(b);
module.exports.a = 2;

// b.js
module.exports.b = 11;
var a = require('./a');
console.log(a);
module.exports.b = 22;

//main.js
var a = require('./a');
console.log(a);

Node加載

  • Node 要求使用 ES6 模塊需要采用.mjs后綴文件名永丝。也就是說(shuō)锹漱,Node 遇到.mjs文件,就認(rèn)為它是ES6 模塊慕嚷,默認(rèn)啟用嚴(yán)格模式哥牍,不必在每個(gè)模塊文件頂部指定"use strict"
  • 如果不希望將后綴名改成.mjs闯冷,可以在項(xiàng)目的package.json文件中砂心,指定type字段為module。一旦設(shè)置了以后蛇耀,該目錄里面的 JS 腳本,就被解釋用 ES6 Module坎弯。如果這時(shí)還要使用 CommonJS 模塊纺涤,那么需要將 CommonJS 模塊腳本的后綴名都改成.cjs译暂。如果沒有type字段,或者type字段為commonjs撩炊,則.js腳本會(huì)被解釋成 CommonJS 模塊外永。
{
   "type": "module"  // 開啟 ES6 Module 模式
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拧咳,隨后出現(xiàn)的幾起案子伯顶,更是在濱河造成了極大的恐慌,老刑警劉巖骆膝,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祭衩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡阅签,警方通過(guò)查閱死者的電腦和手機(jī)掐暮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)政钟,“玉大人路克,你說(shuō)我怎么就攤上這事⊙唬” “怎么了精算?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)碎连。 經(jīng)常有香客問我殖妇,道長(zhǎng),這世上最難降的妖魔是什么破花? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任谦趣,我火速辦了婚禮,結(jié)果婚禮上座每,老公的妹妹穿的比我還像新娘前鹅。我一直安慰自己,他們只是感情好峭梳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布舰绘。 她就那樣靜靜地躺著,像睡著了一般葱椭。 火紅的嫁衣襯著肌膚如雪捂寿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天孵运,我揣著相機(jī)與錄音秦陋,去河邊找鬼。 笑死治笨,一個(gè)胖子當(dāng)著我的面吹牛驳概,可吹牛的內(nèi)容都是我干的赤嚼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼顺又,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼更卒!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起稚照,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蹂空,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后果录,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體上枕,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年雕憔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了姿骏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡斤彼,死狀恐怖分瘦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情琉苇,我是刑警寧澤嘲玫,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站并扇,受9級(jí)特大地震影響去团,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜穷蛹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一土陪、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肴熏,春花似錦鬼雀、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至鸦做,卻和暖如春励烦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背泼诱。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工坛掠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓却音,卻偏偏與公主長(zhǎng)得像改抡,于是被迫代替她去往敵國(guó)和親矢炼。 傳聞我的和親對(duì)象是個(gè)殘疾皇子系瓢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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