国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

nodejs筆記-模塊機制

lscho / 2360人閱讀

摘要:模塊中定義的全局變量只作用于該文件內部,不污染其他模塊。由純編寫的部分稱為內建模塊,例等模塊部分使用編寫。兼容多種模塊規范檢測是否為或者檢測是否為或環境定義為普通模塊將模塊執行結果掛載在對象下

1.為什么要CommonJS規范

javascript存在的缺點

沒有模塊系統

標準庫比較少

沒有標準接口

缺乏包管理系統

CommonJS規范的提出,彌補了javascript沒有標準的缺陷,以達到像Python、Ruby、Java具備的開發大型應用的基礎能力,這樣javascript不僅僅能在客戶端應用還能開發以下應用:

服務端應用

命令行工具

桌面圖形界面應用

混合應用

2.CommonJS的模塊規范 1.模塊引入

使用require()來引入 ,接受一個模塊標識。

let math = require("math");
2.定義模塊

上下文提供里exports對象用于導出模塊或變量,并且是唯一導出出口。在模塊中存在一個module對象,代表模塊自身,exports是它的一個屬性。在nodejs中一個文件就是一個模塊,把方法掛在exports對象上作為屬性即可定義導出

//math.js
exports.add = function(){
    let sum = 0,
        i = 0,
        args = arguments,
        l = args.length;
    while(i < l) {
        sum += args[i ++];
    }
    return sum;
}

在另一個文件require使用

const math = require("./math");
let res = math.add(1, 2, 3);
console.log(res)
//6
3.模塊標識

模塊標識為require()的參數必須是符合小駝峰命名的字符串,或以.、..開頭的相對路徑,或絕對路徑,可以是沒有.js后綴的js文件。
模塊中定義的全局變量只作用于該文件內部,不污染其他模塊。

4.Node模塊實現

Node中引入模塊需經歷以下步驟:

路徑分析

文件定位

編譯執行

Node中模塊分為兩類: 1.Node提供的 "核心模塊",2.用戶編寫的 "文件模塊"
核心模塊Node源碼編譯時已經編譯成二進制執行文件,Node啟動時直接加載進內存中,不需要文件定位和編譯執行兩個步驟,且在路徑分析中優先判斷,加載速度最快。

1.優先從緩存加載

Node會對引入過的模塊進行緩存,核心模塊和文件模塊相同的模塊在二次加載時一律從緩存優先加載(第一優先級),核心模塊緩存檢測優先于文件模塊緩存檢測。

2.路徑分析文件定位
1.模塊標識符分析

標識符分類:

核心模塊,如http、fs、path等

.或..開始的相對路徑文件模塊

以/開頭的絕對路徑模塊

非路徑形式的文件模塊,如自定義的connect模塊 一個文件或一個包

2.自定義模塊
console.log(module.paths)
//[ "c:UsersmaikurakiDesktop
odejs
ode_modules",
  "c:UsersmaikurakiDesktop
ode_modules",
  "c:Usersmaikuraki
ode_modules",
  "c:Users
ode_modules",
  "c:
ode_modules" ]

Node會逐個路徑嘗試知道找到目標文件,模塊路徑越深耗時越多。

3.文件定位

標識符可以不包含文件擴展,這種情況下Node會安裝.js、.json、.node次序補全擴展名。
如果是個包Node會檢測里面的package.json文件Node通過JOSN.parse()解析出包的描述對象去除main屬性指向的文件進行定位,如果沒有該屬性默認查找index.js、index.json、index.node。

3.模塊編譯

在Node中每個文件模塊都是一個對象。
編譯和執行是引入文件模塊的最后一個階段,定位到一個文件后,Node會新建一個模塊對象,然后根據路徑載入并編譯。不同擴展名載入方式:

.js 通過fs模塊讀取后編譯執行

.node 這是C/C++編寫的擴展文件,通過dlopen()方法加載最后編譯生成文件

.json 通過fs模塊讀取文件使用JSON.parse()解析并返回

其他擴展名文件 當做.js文件載入

1.javascript模塊的編譯

在編譯過程中Node對獲取的javascript文件進行的頭尾包裝

(function(exports, require, module, __filename, __dirname) {
    exports.add = (x, y) => {
        return x + y;
    }
})

這樣每個模塊文件直接都進行了作用域隔離,這就是Node對CommonJS規范的實現。

2.C/C++模塊編譯

Node調用process.dlopen()來進行加載執行,windows和*nix平臺下dlopen()通過不同方式實現,通過libuv兼容層進行封裝。

3.JSON文件編譯

Node使用fs模塊讀取json文件內容,使用JSON.parse()得到對象然后給他賦給模塊對象的exports屬性。

4.核心模塊

核心模塊分為C/C++編寫和javascript編寫,C/C++存放在Node項目的src文件下,javascript文件存在lib目錄下。
核心模塊中有些模塊核心部分使用C/C++完成其他使用javascript實現包裝導出。由純C/C++編寫的部分稱為內建模塊,例:buffer、crypto、evals、fs、os等模塊部分使用C/C++編寫。

依賴層關系: 內建模塊(C/C++) ---> 核心模塊(javascript)---> 文件模塊

核心模塊的引入流程
以os原生模塊引入為例

NODE_MODULE(node_os,reg_func) ---> get_builtin_module("node_os") ---> process.binding("os") ---> NativeModule.require("os") ---> require("os")

5.C/C++擴展模塊
1.擴展模塊在不同平臺上編譯和加載過程

Windows
C/C++源碼 ---> VC++ --編譯源碼--> .dll文件 --生成.node文件--> 加載.dll文件 --dlopen()加載--> 導出給javascript使用
*nix
C/C++源碼 ---> g++/gcc --編譯源碼--> .so文件 --生成.node文件--> 加載.so文件 --dlopen()加載--> 導出給javascript使用

2.編譯條件

node-gyp工具

V8引擎C++庫

libuv庫

Node內部庫

其他庫

3.C/C++擴展模塊的加載

require()引入.node文件過程

javascript(require("./hello.node")) ---> 原生模塊(process.dlopen("./hello.node",exports)) ---> libuv(uv_dlopen()/uv_dlsym()) ---> [{*nix: dlopen()/dlsym(), Windows : loadLibraryExW()/GetProcAddress()}]

6.包與NPM

包結構:

package.json 包描述文件

bin 存放可執行位二進制文件

lib 存放javascript文件

doc 存放文檔

test 存放單元測試

7.前后端公用模塊
1.AMD規范

AMD規范是CommonJS規范的一個延伸,定義模塊方法:

define(id?, dependencies?, factory);

define(function() {
    let exports = {};
    exports.sayHello = () => {
        console.log(`hello form module: ${module.id}`);
    }
    return exports;
})
2.CMD規范

CMD與AMD規范的主要區別在于定義模塊和依賴引入的部分。AMD需要在聲明的時候指定所有依賴,通過形參傳遞依賴到模塊中:

define(["dep1", "dep2"], function() {
    return function() {}
})

于AMD規范相比,CMD模塊更接近與Node對CommonJS規范的定義:

define(factory);

在依賴部分,CMD支持動態引入:

define(function(require, exports, module) {
    // module code
})

require,exports,module通過形參傳遞給模塊,在需要依賴模塊時隨時調用require()引入。

兼容多種模塊規范

((name, definition) => {
    //檢測是否為AMD或者CMD
    let hasDefine = typeof define === "function",
        //檢測是否為Node
        hasExports = typeof module !== "undefined" && "module.exports";
    if(hasDefine) {
        //AMD或CMD環境
        define(definition);
    }else if(hasExports) {
        //定義為普通Node模塊
        module.exports = definition();
    }else {
        //將模塊執行結果掛載在window對象下
        this[name] = definition;
    }
})("hello", function() {
    let hello = () => {};
    return helllo;
})

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/107204.html

相關文章

  • Node.js 中度體驗

    摘要:創建簡單應用使用指令來載入模塊創建服務器使用方法創建服務器,并使用方法綁定端口。全局安裝將安裝包放在下。的核心就是事件觸發與事件監聽器功能的封裝。通常我們用于從一個流中獲取數據并將數據傳遞到另外一個流中。壓縮文件為文件壓縮完成。 創建簡單應用 使用 require 指令來載入 http 模塊 var http = require(http); 創建服務器 使用 http.create...

    CastlePeaK 評論0 收藏0
  • 前端模塊化規范筆記

    摘要:目前通行的的模板規范共有兩種和的模塊系統,是參照規范實現的即為服務器端模塊的規范。規范則是非同步加載模塊,允許指定回調函數。 目前通行的Javascript的模板規范共有兩種:CommonJS 和 AMD commonjs nodejs的模塊系統,是參照commonjs規范實現的 commonjs即為服務器端模塊的規范。 commonjs的規范: 根據commonjs規范,一個單獨的...

    honmaple 評論0 收藏0
  • cordova研習筆記(二) —— cordova 6.X 源碼解讀(上)

    摘要:本文源碼為版本。的代碼結構也是一個很經典的定義結構構造函數實例修改函數原型共享實例方法,它提供事件通道上事件的訂閱撤消訂閱調用。 前言 cordova(PhoneGap) 是一個優秀的經典的中間件框架,網上對其源代碼解讀的文章確實不多,本系列文章試著解讀一下,以便對cordova 框架的原理理解得更深入。本文源碼為cordova android版本6.1.2。 源碼結構 我們使用IDE...

    Java_oldboy 評論0 收藏0
  • Vue入坑筆記

    摘要:近段時間常使用開發,寫點記錄,避免時間久之忘了。安裝教程查看是否已安裝,在中輸入若已安裝則輸出版本號。繼承報錯可能是文件路徑問題。當和繼承的不同時在文件夾內外的話,會出現該錯誤。 近段時間常使用vue-cli開發,寫點記錄,避免時間久之忘了。 環境 1. nodejs  vue-cli開發基于nodejs環境,確保開發的環境中已安裝了nodejs。  安裝教程 https://www....

    superw 評論0 收藏0
  • 零碎筆記:瀏覽器訪問一個網站所經歷的步驟

    摘要:瀏覽器拿到了簡書網的完整的頁面代碼,在解析和渲染這個頁面的時候,里面的圖片靜態資源,他們同樣也是一個個請求都需要經過上面的主要的七個步驟。瀏覽器根據拿到的資源對頁面進行渲染,最終把一個完整的頁面呈現給了用戶。 瀏覽器訪問一個網站所經歷的步驟 Chrome搜索自身的DNS緩存 搜索操作系統自身的DNS緩存(瀏覽器沒有找到緩存或緩存已經失效)查看Chrome瀏覽器的DNS緩存信息(chr...

    張金寶 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<