node 模塊機(jī)制

模塊引用

示例代碼如下:

const fs = require("fs");

在 CommonJS 規(guī)范中桦踊,require 接受一個模塊標(biāo)志亚享,以此引入模塊的 API劣欢。

模塊提供了 exports 對象來導(dǎo)出方法或變量,另外還有一個 module 對象纪蜒,該對象即模塊本身,而在 nodejs 中此叠,文件就是模塊纯续。在 module 對象上有一個 module.exports 屬性,這是其導(dǎo)出的內(nèi)容灭袁,變量 exports 指向的地址就是 module.exports猬错。也就是說:

module.exports === exports

這里注意,可以在 exports 上添加屬性或方法來導(dǎo)出茸歧,但不可修改 exports 本身的值倦炒,因為改了以后,exports 不在指向 module.exports, 也就不會被導(dǎo)出举娩。如果想要導(dǎo)出一個類析校,可以:

let A = {}
A.prototype.foo = foo;
...
module.exports = A;

node 模塊實現(xiàn)

node 會將加載過的模塊放入緩存构罗,下次引用直接從緩存加載。

路徑分析 和 文件定位

  • 核心模塊智玻,如 fs 遂唧、path、http 等吊奢,直接引用模塊名盖彭。node 啟動時就已經(jīng)加載到內(nèi)存,加載速度最快
  • "." 或".."開頭页滚,相對路徑查找召边,知道路徑,查找快裹驰,但仍需動態(tài)加載隧熙,速度稍慢
  • "/"開頭,從根目錄查找幻林,同上
  • 自定義模塊贞盯,根據(jù) module.paths 變量遞歸向上查找 node_modules 目錄

文件定位

require 查找模塊時,需要 fs 模塊同步阻塞的判斷是否存在沪饺。

require 時一般不需要指定文件后綴名躏敢,但也可以加上。如果沒有后綴整葡,node 會依次在對應(yīng)路徑查找 .js件余、.json.node遭居。如果是后兩種啼器,加上后綴名查找會稍快。

很可能最后找不到對應(yīng)的.js魏滚、.json镀首、.node文件,但找到的是一個目錄鼠次。則會查看該目錄package.json下main 項對應(yīng)的值更哄。示例如下:

"version": "1.0.0",
  "description": "",
  "main": "webpack.config.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },

于是找到了 webpack.config.js 文件。如果沒有 main 項或者不存在 package.json腥寇,則會依次查找 index.js , index.json, index.node成翩。如果仍然沒有,就按照 module.path 數(shù)組依次遞歸向上查找赦役。最終找不到麻敌,則拋出異常。

模塊編譯

node 中模塊定義如下:

function Module(id, parent) {
  this.id = id;
  this.parent = parent;
  this.exports = {};
  if(parent && parent.children){
    parent.children.push(this);
  }

  this.filename = null; //定義時還不能確定該值
  this.loaded = false;
  this.children = [];
}

定位到具體文件后掂摔,對不同類型的文件操作不一樣:

  • .js 文件术羔,通過 fs 模塊同步讀取后編譯執(zhí)行
  • .node 文件赢赊,這是 c/c++ 寫的擴(kuò)展文件
  • .json 文件,讀取后通過 JSON.parse() 解析并返回結(jié)果

每一個編譯后的模塊都被緩存起來级历。

javaScript 模塊的編譯

我們前面知道有 require 方法和 exports 對象释移,可是這些變量和方法在哪里聲明的呢?實際上寥殖,node 對讀取到的 js 文件做了包裝:

(function (exports, require, module, __filename, __dirname) {
  // module content
});

node 讀取 js 文件后執(zhí)行的就是這個包裝函數(shù)玩讳,然后得到 module.exports 。

(待續(xù))

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚼贡,一起剝皮案震驚了整個濱河市熏纯,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌粤策,老刑警劉巖樟澜,帶你破解...
    沈念sama閱讀 211,423評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異掐场,居然都是意外死亡往扔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,147評論 2 385
  • 文/潘曉璐 我一進(jìn)店門熊户,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人吭服,你說我怎么就攤上這事嚷堡。” “怎么了艇棕?”我有些...
    開封第一講書人閱讀 157,019評論 0 348
  • 文/不壞的土叔 我叫張陵蝌戒,是天一觀的道長。 經(jīng)常有香客問我沼琉,道長北苟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,443評論 1 283
  • 正文 為了忘掉前任打瘪,我火速辦了婚禮友鼻,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘闺骚。我一直安慰自己彩扔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,535評論 6 385
  • 文/花漫 我一把揭開白布僻爽。 她就那樣靜靜地躺著虫碉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胸梆。 梳的紋絲不亂的頭發(fā)上敦捧,一...
    開封第一講書人閱讀 49,798評論 1 290
  • 那天须板,我揣著相機(jī)與錄音,去河邊找鬼兢卵。 笑死习瑰,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的济蝉。 我是一名探鬼主播杰刽,決...
    沈念sama閱讀 38,941評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼王滤!你這毒婦竟也來了贺嫂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,704評論 0 266
  • 序言:老撾萬榮一對情侶失蹤雁乡,失蹤者是張志新(化名)和其女友劉穎第喳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體踱稍,經(jīng)...
    沈念sama閱讀 44,152評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡曲饱,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,494評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了珠月。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扩淀。...
    茶點故事閱讀 38,629評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖啤挎,靈堂內(nèi)的尸體忽然破棺而出驻谆,到底是詐尸還是另有隱情,我是刑警寧澤庆聘,帶...
    沈念sama閱讀 34,295評論 4 329
  • 正文 年R本政府宣布胜臊,位于F島的核電站,受9級特大地震影響伙判,放射性物質(zhì)發(fā)生泄漏象对。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,901評論 3 313
  • 文/蒙蒙 一宴抚、第九天 我趴在偏房一處隱蔽的房頂上張望勒魔。 院中可真熱鬧,春花似錦酱塔、人聲如沸沥邻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唐全。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間邮利,已是汗流浹背弥雹。 一陣腳步聲響...
    開封第一講書人閱讀 31,978評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留延届,地道東北人剪勿。 一個月前我還...
    沈念sama閱讀 46,333評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像方庭,于是被迫代替她去往敵國和親厕吉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,499評論 2 348

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