首頁 web前端 js教程 Node.js中的模組機制學習筆記_node.js

Node.js中的模組機制學習筆記_node.js

May 16, 2016 pm 04:32 PM
node.js

Javascript自誕生以來,曾經沒有人拿它當做一門程式語言。在Web 1.0時代,這種腳本語言主要被用來做表單驗證和網頁特效。直到Web 2.0時代,前端工程師利用它大大提升了網頁上的使用者體驗,JS才被廣泛重視。在JS逐漸流行的過程中,它大致經歷了工具類別庫、元件庫、前端框架、前端應用的變化。 Javascript先天缺乏一項功能:模組,而CommonJS規範的出現則彌補了這個缺陷。本文將介紹CommonJS規格及Node的模組機制。

在其他高階語言中,Java有類別文件,Python有import機制,PHP有include和require。而JS透過<script>標籤引入程式碼的方式顯得雜亂無章。過去人們不得不用命名空間等方式來人為地約束程式碼,直到CommonJS規格的出現,前後端的Javascript才得以實現大一統。 Node借鑒了CommonJS的Modules規格實作了一套非常易用的模組系統。 </script>

1. CommonJS模組規格

CommonJS的模組規格分為3個部分:

1).模組引用:透過require()方法並傳入一個模組標識來引入一個模組的API到當前上下文中,如var math = require('math');
2).模組定義:透過exports物件來導出目前模組的方法或變數。模組中還存在一個module對象,exports其實是module的屬性。在Node中,一個檔案就是一個模組,模組內的「全域變數」對外都不可見,只有掛載在exports上的屬性才是公開的,如exports.add = function() {}; exports.PI = 3.1415926;
3).模組標識:實際上就是傳遞給require()的參數,如上述的'math',它必須是符合camel命名法的字串,或者是以“.”“..”開頭的相對路徑或絕對路徑,它可以沒有檔名後綴“.js”

2. Node模組實作過程

在Node中,模組分為兩類:一類是Node本身提供的核心模組,另一類是使用者自己寫的檔案模組。核心模組有一部分在Node原始碼的編譯過程中,編譯成了二進位文件,在Node啟動時核心模組就被直接載入進記憶體中,所以它的載入速度是最快的。文件模組則是在運行時動態加載,需要經歷三個步驟:路徑分析,文件定位,編譯執行。請注意,Node對引入過的模組都會進行緩存,以減少二次引入時的開銷,並對相同模組的二次加載都採用最優先從緩存加載的策略。

2.1 路徑分析

路徑分析主要分析上述提到的模組標識符,主要分為以下幾類:

1)、核心模組,如http、fs、path等
2)、.或..開始的相對路徑檔模組
3)、以/開始的絕對路徑檔模組
4)、自訂檔案模組,可能是一個檔案或套件的形式。 Node會根據模組路徑數組module.paths來逐一嘗試查找目標文件,通常是沿著當前目錄逐級向上直到根目錄查找名為node_modules的目錄,所以這是查找最費時的一種方式。

2.2 檔案定位

在路徑分析的基礎上,檔案定位需要注意以下細節:

1)、檔案副檔名分析:由於CommonJS規格允許模組識別不填入副檔名,Node會按.js、.json、.node的次序不足副檔名,依序嘗試
2)、目錄分析和套件:若經過上述文件副檔名分析後沒有查找到對應文件,卻得到一個目錄,Node會把目錄當作一個包來處理

2.3 編譯執行

定位到特定檔案後,Node會新建一個模組對象,依照路徑載入並編譯。對於不同的副檔名,載入方法有所不同:

1)、.js檔:透過fs模組同步讀取檔並編譯執行
2)、.node檔:這是用C/C 寫的擴充文件,透過dlopen()方法載入
3)、.json檔:透過fs模組同步讀取文件,用JSON.parse()解析回傳結果
4)、其餘副檔名檔:都被當做.js檔載入

我們知道每個模組檔案中預設都存在著require、exports、module這3個變量,甚至在Node的API文件中,我們知道每個模組還有filename、dirname這2個變數的存在,它們是從何而來的呢? Node的模組又是怎麼做到宣告的「全域變數」其實是不會污染到其他模組的?事實上,Node在編譯JS模組過程中會對檔案內容進行頭尾包裝。下面是一個JS檔案經過頭尾包裝的範例:

複製程式碼 程式碼如下:

(function(exports, require, module, __filename, __dirname) {
    /* 中間是JS檔案的實際內容 */
    var math = require('math');
    exports.area = function(radius) {
        return Math.PI * radius * radius;
    };
    /* JS檔案的實際內容結束 */
});

這樣每個模組檔案之間都進行了作用域隔離,同時require、exports、module等變數也被注入到了模組的上下文當中。這就是Node對CommonJS模組規範的實作。關於C/C 模組及Node核心模組的編譯過程較為複雜,不再贅述。

3. 模組呼叫堆疊

有必要先明確Node中各種模組的呼叫關係,如下圖所示:

C/C 內建模區塊是最底層的模組,屬於核心模組,主要提供API給Javascript核心模組和第三方Javascript檔案模組調用,實際上幾乎不會接觸到此類模組。 Javascript核心模組主要職責有兩種:一種是作為C/C 內建模塊的封裝層和橋接層供文件模組調用,另一種是純粹的功能模組,不需要跟底層打交道。文件模組通常由第三方編寫,包括普通Javascript模組和C/C 擴充模組。

4. 包與NPM

4.1 套件結構

套件本質上是一個存檔檔案(一般為.zip或.tar.gz),安裝後解壓縮還原為目錄。 CommonJS的包規格由包結構和包描述文件兩部分組成。一個完全符合CommonJS規範的套件結構應包含以下檔案:

1).package.json:套件描述檔
2).bin:存放可執行二進位的目錄
3).lib:存放Javascript程式碼的目錄
4).doc:存放文件的目錄
5).test:存放單元測試用例的目錄

4.2 包裝描述檔

套件描述檔是一個JSON檔案-package.json,位於套件的根目錄下,是套件的重要組成部分,用於描述套件的概況資訊。後面要提到的NPM的所有行為都與這個文件的欄位息息相關。以下將以知名Web框架express專案的package.json檔案為例說明一些常用欄位的意義。

1).name:包名
2).description:包簡介
3).version:版本號,需遵照“語意化的版本控制”,參考http://semver.org/
4).dependencies:使用目前套件所需依賴的套件清單。這個屬性十分重要,NPM會透過這個屬性自動載入依賴的套件
5).repositories:託管原始碼的位置清單

其餘欄位的用法可以參考NPM package.json說明

4.3 NPM常用功能

NPM(node package manager),通常稱為node套件管理器。它的主要功能是管理node包,包括:安裝、解除安裝、更新、檢視、搜尋、發布等。

4.3.1 NPM套件安裝

Node包的安裝分為兩種:本機安裝、全域安裝。兩者的差異如下:

1).本機安裝npm install :package會被下載到目前所在目錄,也只能在目前目錄下使用。
2).全域安裝npm install -g :package會被下載到到特定的系統目錄下,安裝的package能夠在所有目錄下使用。

4.3.2 NPM套件管理

以下以grunt-cli(grunt命令列工具)為例,列出常用的套件管理指令:

1).npm install:安裝package.json檔案的dependencies和devDependencies欄位宣告的所有套件
2).npm install grunt-cli@0.1.9:安裝特定版本的grunt-cli
3).npm install grunt-contrib-copy --save:安裝grunt-contrib-copy,同時保存該依賴到package.json檔案
4).npm uninstall grunt-cli:卸載套件
5).npm list:查看安裝了哪些套件
6).npm publish :發布包

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

圖文詳解Node V8引擎的記憶體和GC 圖文詳解Node V8引擎的記憶體和GC Mar 29, 2023 pm 06:02 PM

這篇文章帶大家深入了解NodeJS V8引擎的記憶體和垃圾回收器(GC),希望對大家有幫助!

一文聊聊Node中的記憶體控制 一文聊聊Node中的記憶體控制 Apr 26, 2023 pm 05:37 PM

基於無阻塞、事件驅動建立的Node服務,具有記憶體消耗低的優點,非常適合處理海量的網路請求。在海量請求的前提下,就需要考慮「記憶體控制」的相關問題了。 1. V8的垃圾回收機制與記憶體限制 Js由垃圾回收機

聊聊如何選擇一個最好的Node.js Docker映像? 聊聊如何選擇一個最好的Node.js Docker映像? Dec 13, 2022 pm 08:00 PM

選擇一個Node的Docker映像看起來像是小事,但是映像的大小和潛在漏洞可能會對你的CI/CD流程和安全造成重大的影響。那我們要如何選擇一個最好Node.js Docker映像呢?

Node.js 19正式發布,聊聊它的 6 大功能! Node.js 19正式發布,聊聊它的 6 大功能! Nov 16, 2022 pm 08:34 PM

Node 19已正式發布,以下這篇文章就來帶大家詳解了解Node.js 19的 6 大特性,希望對大家有幫助!

深入聊聊Node中的File模組 深入聊聊Node中的File模組 Apr 24, 2023 pm 05:49 PM

文件模組是對底層文件操作的封裝,例如文件讀寫/打開關閉/刪除添加等等文件模組最大的特點就是所有的方法都提供的**同步**和**異步**兩個版本,具有sync 字尾的方法都是同步方法,沒有的都是異

聊聊Node.js中的 GC (垃圾回收)機制 聊聊Node.js中的 GC (垃圾回收)機制 Nov 29, 2022 pm 08:44 PM

Node.js 是如何做 GC (垃圾回收)的?下面這篇文章就來帶大家了解一下。

一起聊聊Node中的事件循環 一起聊聊Node中的事件循環 Apr 11, 2023 pm 07:08 PM

事件循環是 Node.js 的基本組成部分,透過確保主執行緒不被阻塞來實現非同步編程,了解事件循環對建立高效應用程式至關重要。以下這篇文章就來帶大家深入了解Node中的事件循環 ,希望對大家有幫助!

深入了解Node中的Buffer 深入了解Node中的Buffer Apr 25, 2023 pm 07:49 PM

一開始的時候 JS 只在瀏覽器端運行,對於 Unicode 編碼的字串容易處理,但對於二進位和非 Unicode 編碼的字串處理困難。並且二進制是電腦最底層的資料格式,視訊/音訊/程式/網路包

See all articles