<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        node.jsrequire()源碼解讀_node.js

        來源:懂視網 責編:小采 時間:2020-11-27 21:47:11
        文檔

        node.jsrequire()源碼解讀_node.js

        node.jsrequire()源碼解讀_node.js:2009年,Node.js 項目誕生,所有模塊一律為 CommonJS 格式。 時至今日,Node.js 的模塊倉庫 npmjs.com ,已經存放了15萬個模塊,其中絕大部分都是 CommonJS 格式。 這種格式的核心就是 require 語句,模塊通過它加載。學習 Node.js ,必學如何使
        推薦度:
        導讀node.jsrequire()源碼解讀_node.js:2009年,Node.js 項目誕生,所有模塊一律為 CommonJS 格式。 時至今日,Node.js 的模塊倉庫 npmjs.com ,已經存放了15萬個模塊,其中絕大部分都是 CommonJS 格式。 這種格式的核心就是 require 語句,模塊通過它加載。學習 Node.js ,必學如何使
        2009年,Node.js 項目誕生,所有模塊一律為 CommonJS 格式。

        時至今日,Node.js 的模塊倉庫 npmjs.com ,已經存放了15萬個模塊,其中絕大部分都是 CommonJS 格式。

        這種格式的核心就是 require 語句,模塊通過它加載。學習 Node.js ,必學如何使用 require 語句。本文通過源碼分析,詳細介紹 require 語句的內部運行機制,幫你理解 Node.js 的模塊機制。

        一、require() 的基本用法

        分析源碼之前,先介紹 require 語句的內部邏輯。如果你只想了解 require 的用法,只看這一段就夠了。

        下面的內容翻譯自《Node使用手冊》。

        代碼如下:
        當 Node 遇到 require(X) 時,按下面的順序處理。

        (1)如果 X 是內置模塊(比如 require('http'))
          a. 返回該模塊。
          b. 不再繼續執行。

        (2)如果 X 以 "./" 或者 "/" 或者 "../" 開頭
          a. 根據 X 所在的父模塊,確定 X 的絕對路徑。
          b. 將 X 當成文件,依次查找下面文件,只要其中有一個存在,就返回該文件,不再繼續執行。

        X
        X.js
        X.json
        X.node

          c. 將 X 當成目錄,依次查找下面文件,只要其中有一個存在,就返回該文件,不再繼續執行。

        X/package.json(main字段)
        X/index.js
        X/index.json
        X/index.node

        (3)如果 X 不帶路徑
          a. 根據 X 所在的父模塊,確定 X 可能的安裝目錄。
          b. 依次在每個目錄中,將 X 當成文件名或目錄名加載。

        (4) 拋出 "not found"

        請看一個例子。

        當前腳本文件 /home/ry/projects/foo.js 執行了 require('bar') ,這屬于上面的第三種情況。Node 內部運行過程如下。

        首先,確定 x 的絕對路徑可能是下面這些位置,依次搜索每一個目錄。

        代碼如下:
        /home/ry/projects/node_modules/bar
        /home/ry/node_modules/bar
        /home/node_modules/bar
        /node_modules/bar

        搜索時,Node 先將 bar 當成文件名,依次嘗試加載下面這些文件,只要有一個成功就返回。

        如果都不成功,說明 bar 可能是目錄名,于是依次嘗試加載下面這些文件。

        代碼如下:
        bar/package.json(main字段)
        bar/index.js
        bar/index.json
        bar/index.node

        如果在所有目錄中,都無法找到 bar 對應的文件或目錄,就拋出一個錯誤。

        二、Module 構造函數

        了解內部邏輯以后,下面就來看源碼。

        require 的源碼在 Node 的 lib/module.js 文件。為了便于理解,本文引用的源碼是簡化過的,并且刪除了原作者的注釋。

        上面代碼中,Node 定義了一個構造函數 Module,所有的模塊都是 Module 的實例??梢钥吹剑斍澳K(module.js)也是 Module 的一個實例。

        每個實例都有自己的屬性。下面通過一個例子,看看這些屬性的值是什么。新建一個腳本文件 a.js 。

        運行這個腳本。

        可以看到,如果沒有父模塊,直接調用當前模塊,parent 屬性就是 null,id 屬性就是一個點。filename 屬性是模塊的絕對路徑,path 屬性是一個數組,包含了模塊可能的位置。另外,輸出這些內容時,模塊還沒有全部加載,所以 loaded 屬性為 false 。

        新建另一個腳本文件 b.js,讓其調用 a.js 。

        運行 b.js 。

        上面代碼中,由于 a.js 被 b.js 調用,所以 parent 屬性指向 b.js 模塊,id 屬性和 filename 屬性一致,都是模塊的絕對路徑。

        三、模塊實例的 require 方法

        每個模塊實例都有一個 require 方法。

        由此可知,require 并不是全局性命令,而是每個模塊提供的一個內部方法,也就是說,只有在模塊內部才能使用 require 命令(唯一的例外是 REPL 環境)。另外,require 其實內部調用 Module._load 方法。

        下面來看 Module._load 的源碼。

        輸出模塊的exports屬性 return module.exports; };

        上面代碼中,首先解析出模塊的絕對路徑(filename),以它作為模塊的識別符。然后,如果模塊已經在緩存中,就從緩存取出;如果不在緩存中,就加載模塊。

        因此,Module._load 的關鍵步驟是兩個。

        代碼如下:
        ◾Module._resolveFilename() :確定模塊的絕對路徑
        ◾module.load():加載模塊

        四、模塊的絕對路徑

        下面是 Module._resolveFilename 方法的源碼。

        上面代碼中,在 Module.resolveFilename 方法內部,又調用了兩個方法 Module.resolveLookupPaths() 和 Module._findPath() ,前者用來列出可能的路徑,后者用來確認哪一個路徑為真。

        為了簡潔起見,這里只給出 Module._resolveLookupPaths() 的運行結果。

        代碼如下:
        [ '/home/ruanyf/tmp/node_modules',
        '/home/ruanyf/node_modules',
        '/home/node_modules',
        '/node_modules'
        '/home/ruanyf/.node_modules',
        '/home/ruanyf/.node_libraries',
        '$Prefix/lib/node' ]

        上面的數組,就是模塊所有可能的路徑?;旧鲜牵瑥漠斍奥窂介_始一級級向上尋找 node_modules 子目錄。最后那三個路徑,主要是為了歷史原因保持兼容,實際上已經很少用了。

        有了可能的路徑以后,下面就是 Module._findPath() 的源碼,用來確定到底哪一個是正確路徑。

        經過上面代碼,就可以找到模塊的絕對路徑了。

        有時在項目代碼中,需要調用模塊的絕對路徑,那么除了 module.filename ,Node 還提供一個 require.resolve 方法,供外部調用,用于從模塊名取到絕對路徑。

        五、加載模塊

        有了模塊的絕對路徑,就可以加載該模塊了。下面是 module.load 方法的源碼。

        上面代碼中,首先確定模塊的后綴名,不同的后綴名對應不同的加載方法。下面是 .js 和 .json 后綴名對應的處理方法。

        這里只討論 js 文件的加載。首先,將模塊文件讀取成字符串,然后剝離 utf8 編碼特有的BOM文件頭,最后編譯該模塊。

        module._compile 方法用于模塊的編譯。

        上面的代碼基本等同于下面的形式。

        也就是說,模塊的加載實質上就是,注入exports、require、module三個全局變量,然后執行模塊的源碼,然后將模塊的 exports 變量的值輸出。

        (完)

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        node.jsrequire()源碼解讀_node.js

        node.jsrequire()源碼解讀_node.js:2009年,Node.js 項目誕生,所有模塊一律為 CommonJS 格式。 時至今日,Node.js 的模塊倉庫 npmjs.com ,已經存放了15萬個模塊,其中絕大部分都是 CommonJS 格式。 這種格式的核心就是 require 語句,模塊通過它加載。學習 Node.js ,必學如何使
        推薦度:
        標簽: js nod 源碼
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 精品亚洲麻豆1区2区3区| 亚洲啪啪AV无码片| 亚洲国产成人手机在线观看| 最近免费中文字幕大全免费 | caoporn成人免费公开| 国产精品免费播放| 国产成人亚洲午夜电影| 免费国产成人午夜电影| 国产免费一级高清淫曰本片| 中文字幕精品亚洲无线码一区| 久久www免费人成精品香蕉| 亚洲中文字幕无码久久2017| 黄网站免费在线观看| 久久久久久亚洲精品中文字幕| 日韩精品极品视频在线观看免费| 久久精品视频亚洲| 国产福利在线免费| 在线亚洲精品视频| 狠狠综合久久综合88亚洲| 久久国产精品成人免费| 亚洲丝袜中文字幕| 国产精品国产免费无码专区不卡 | 九九99热免费最新版| 午夜影视日本亚洲欧洲精品一区| 18成禁人视频免费网站| 亚洲gay片在线gv网站| 亚洲综合另类小说色区色噜噜| 免费观看91视频| 亚洲成A人片在线播放器| 亚洲精品国产自在久久| 国产免费AV片在线观看| 亚洲av无码久久忘忧草| 国产成人免费全部网站 | 0588影视手机免费看片| 久久亚洲精品无码av| 狠狠亚洲狠狠欧洲2019| 人成午夜免费视频在线观看| 黄色片网站在线免费观看| 亚洲成人动漫在线| 国产18禁黄网站免费观看| 91在线视频免费观看|