1. 程式人生 > >Node中對CommonJS模組規範的實現

Node中對CommonJS模組規範的實現

一、首先了解一下CommonJS的模組規範

1.模組引用
   在CommonJS規範中,存在require( )方法,它接受一個模組標識,用來引入一個模組中API

2.模組定義
   既然在模組中有require( )方法來引入外部模組,那麼也存在某個方法來匯出模組的方法或者變數,對,它就是export物件。在模組中還存在一個module物件,它代表的是模組的本身,而export是module的屬性。
   code:

//  method.js
export.add = function(n){
    var sum = 0,i=0;
    while(i<n){
        sum
+= i; } return sum; }

在另一個檔案中引入模組並呼叫定義的屬性和方法:

//  use.js
var method = required("method");
export.fn = function(val){
    return method.add(val);
}

3.模組標識
   所謂的模組標識其實就是傳遞給required( )方法的引數,它有如下的要求:
   (1)它必須是符合小駝峰命名的字串
   (2)或者是以 ...開頭的相對路徑,或者絕對路徑
   (3)其實它可以沒有檔名字尾
   
CommonJS的這套模組匯出,引入的機制使得使用者完全不必考慮變數汙染,名稱空間等問題

二、Node模組的實現

Node中的模組分為兩大類:1.核心模組 (example:http,fs等等),2.使用者定義的檔案模組(如上面程式碼中的method和use模組)

在Node中實現模組分為一下三個步驟:
   (1)路徑分析
   (2)檔案定位
   (3)編譯執行

   在Node程序啟動時,部分核心模組直接載入到記憶體之中,此時檔案定位和編譯執行兩個步驟可以省略,並且在路徑分析中優先判斷,所以它的載入速度是最快的;而檔案模組,是在執行時動態載入,需要完整的路徑分析,檔案定位,編譯執行過程,所以速度比核心模組載入慢很多。

1.優先從快取中載入
   就像瀏覽器為了提高前端的效能快取靜態資源一樣,Node引入過的模組都會進行快取,以減少第二次載入時的開銷。
   不管是核心模組還是檔案模組,require( )對相同的模組的二次載入都採用快取優先,不同之處在於對核心模組的快取檢查的優先順序高於檔案模組。

2.路徑分析和檔案定位
(1)模組識別符號分析
   基本的前面我都有提到過,另外除了核心模組和以路徑形式的檔案模組,這裡再補充一種——自定義模組:
   自定義模組值得是非核心模組,也不是路徑形式的識別符號。它是一種特殊的檔案模組,可能是一個檔案或者包的形式,這類模組的查詢是最費時間的,也是所有引入方式中最慢的一種,因為它需要通過模組路徑一次次的嘗試搜尋,直到找到目標檔案為止。

(2)檔案定位
   關於檔案定位,有一些細節需要注意的:副檔名的分析,目錄和包的處理。
   1.副檔名分析
   在CommonJS規範中允許識別符號中不包含副檔名,一般這種情況Node會按.js、.node、.json的次序補充副檔名,然後依次查詢.
   2.目錄分析和包
   在分析識別符號的過程中,require( ) 通過分析副檔名之後可能並沒有找到此檔案,但是會的得到一個目錄,這種情況經常在引入自定義模組和逐個查詢時經常會出現,此時Node會將目錄當做一個包來處理。
   首先,Node在當前目錄查詢package.json(不懂的百度瞭解一下),通過JSON.parse()解析出包描述物件,從中取出main屬性指定的檔名進行定位。而如果main屬性指定的檔名錯誤,或者壓根沒有package.json檔案,Node會將index當作預設檔名,然後按照.js、.node、.json的字尾次序依次查詢。
如果在目錄分析中沒有成功找到任何檔案,則自定義模組進入下一個模組路徑進行查詢。如果模組路徑陣列被遍歷完,還是沒有找到目標檔案,則會丟擲一個查詢失敗的錯誤。

3.模組編譯
編譯執行是引入檔案模組的最後一個階段,找到目標檔案之後,Node會新建一個模組物件(每一個檔案模組都是一個物件),然後根據路徑載入並編譯。
每個不同的檔名字尾採用不同的載入方法:
.js ——— 通過fs模組同步讀取檔案後編譯執行 (JS編譯的實現
.node ——— 使用C/C++編寫的擴充套件檔案
.json ——— 通過fs模組同步讀取檔案後,用JSON.parse( ) 解析
其餘的副檔名檔案 ——— 全當作.js載入
瞭解更多

相關推薦

NodeCommonJS模組規範實現

一、首先了解一下CommonJS的模組規範 1.模組引用    在CommonJS規範中,存在require( )方法,它接受一個模組標識,用來引入一個模組中API 2.模組定義    既然在模組中有require( )方法來引入外部模組,那麼也存在某個

Nodeconsole.log的同步實現

console.log相信使用過js的朋友都不會陌生,對於我這種前端轉過來的node開發者,用起這個函式更是毫不手軟,使用它把需要的資訊列印到標準輸出,覺得就是1+1=2那麼正常,但是有天在網上看到一個問題console.log到底是非同步還是同步?我覺得很詫異,這還是個問題麼?當然是同步啦。但是問題的答案出

node的url模組解析結果

1. URL模組作用: url 模組用於處理與解析 URL。 使用方法如下: const url = require('url'); 2. URL 字串與 URL 物件 URL 字串是結構化的字串,包含多個含義不同的組成部分。 解析字串後返回的 URL 物件,每個屬性對應

仿京東購物車列表模組實現【以及通過Builder的方式建立dialog彈窗 鏈式呼叫】

前段時間見群裡有個小夥伴,發了一張電商專案中比較常見的購物車列表的效果圖,問這樣的購物車列表如何實現?我們第一反應就是用ExpandableListView來實現,在上一篇部落格中我們詳細的分析了比較實用而且又炫酷的 RecyclerView的ItemDecor

CommonJS模組規範與NodeJS的模組系統底層原理

原諒我標題黨 其實也沒有非常深入底層 在瞭解NodeJS模組之前 首先來科普一下什麼是CommonJS CommonJS規範 它為JavaScript制定一套規範——希望JavaScript能在任何地方執行 使其具備開發大型應用的能力

Object-C自定義類實現協議

如果嘗試使用自定義類(例如,人類(person類)、地址簿類(myBook類)、分數類(Fraction類))中的copy方法,如 myBook = [myBook mutableCopy]; person = [Person copy];等類似的操作,將會收到一條異

node 控制檯的清空方式

1、    process.stdout.write('\n'); 2、   process.stdout.write('\033[0f'); 3、   process.stdout.write('\033[2J');

Node.js入門- CommonJs 和 Nodejs 自定義模組

CommonJs 和 Nodejs 中自定義模組 一、什麼是 CommonJs? CommonJS 是模組化的標準,nodejs 是 CommonJS(模組化)的實現 二、Nodejs 中的模組化 2.1 在 Node 中,模組分為兩類: 一類是 Node 提供

再談 JS模組規範CommonJS,AMD,CMD)來自玉伯的seajs分析

                隨著網際網路的飛速發展,前端開發越來越複雜。本文將從實際專案中遇到的問題出發,講述模組化能解決哪些問題,以及如何使用 Sea.js 進行前端的模組化開發。惱人的命名衝突我們從一個簡單的習慣出發。我做專案時,常常會將一些通用的、底層的功能抽象出來,獨立成一個個函式,比如funct

node - 非同步執行,在佇列的底部,es5,es6公有繼承,nodeutil模組實現繼承和util模組的其他常用方法(很重要)

//非同步的,在當前佇列的底部 process.nextTick(function(){ console.log("1") }) //第二個佇列中 setImmediate(function(){ console.log("222") }) setTimeout(f

node.js通過stream模組實現自定義流

有些時候我們需要自定義一些流,來操作特殊物件,node.js中為我們提供了一些基本流類。 我們新建立的流類需要繼承四個基本流類之一(stream.Writeable,stream.Readable,stream.Duplex,stream.Transform),並確保呼叫了父類建構函式。  

前端模組化(一)nodeJSCommonJS規範

序言 模組化,大家用vue,react等東西,都會接觸到像exports,module.exports,export,export default,require,define,import等等欄位,感覺很多人對於這些東西還是分不清,概念非常的模糊,便想著寫這麼一篇文章,一

Node.js使用fs模組實現本地圖片下載

使用node.js自帶的http模組與fs模組搭建了一個可以下載圖片的伺服器。專案的github:https://github.com/junhaogz215/getImage效果如下:執行伺服器之後在位址列輸入http://localhost:3000可跳轉到index.h

淺析JS的模塊規範CommonJS,AMD,CMD) http://www.2cto.com/kf/201411/348276.html

cpu 重要 mat 只有一個 targe () actor cti 最重要的 如果你聽過js模塊化這個東西,那麽你就應該聽過或CommonJS或AMD甚至是CMD這些規範咯,我也聽過,但之前也真的是聽聽而已。 現在就看看吧,這些規範到底是啥東西,幹嘛的。

理解JS的模塊規範CommonJS,AMD,CMD)

site 繼續 arr 包管理器 color sea 文件依賴 避免 說我   隨著互聯網的飛速發展,前端開發越來越復雜。本文將從實際項目中遇到的問題出發,講述模塊化能解決哪些問題,以及如何使用 Sea.js 進行前端的模塊化開發。 惱人的命名沖突   我們從一個簡單的習慣

QTableView使用Delegate方式來實現特定列的文本進行換行

dwr raw pan 文本 detail ring -s dem 代碼 問題:由於表格的一個列中,有個別文本過長,默認情況下,QTableView不支持對某列的文本換行,所以需要通過Delegate方式來實現這樣的效果 頭文件的Delegate 1 #pragma o

nodehttps請求 | 實現https的請求,獲取圖片,然後轉成base64字節碼

str2 gpo end callback func www. lB nod div get請求 下面實現https的請求,獲取圖片,然後轉成base64字節碼 this.checkCodeUrl = ‘https://www.test.com/kaptcha.jsp‘

C語言如何實現C++象屬性和方法

討論 button c語言 對象 ron oid 技術分享 數據 而在   在C++中,我們常見到用類定義一個對象,這個對象可以有他自己的屬性(數據)和方法(函數),而在C語言的正常語法中,是禁止在結構體中定義函數的。   在一個關於觸摸屏的驅動程序中發現,用C語言的也可以

node-刪除指定屬性失效問題-JSON.parse實例化

修改 ole log 字段 foreach ons 對象 java json 需求描述:   刪除 _body 對象裏的 code 字段。用 detele 刪除後輸出的_body 裏仍有 code 字段。 body是從後臺得到的json串,所以要先 parse 轉換成對

JDBC上關於資料庫多表操作一對多關係和多多關係的實現方法--轉

  原文地址---- https://www.cnblogs.com/pangguoming/p/7028322.html 黑馬程式設計師 我們知道,在設計一個Java bean的時候,要把這些BEAN 的資料存放在資料庫中的表結構,然而這些資料庫中的表直接又有些特殊