成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

nodejs筆記-模塊機(jī)制

lscho / 2380人閱讀

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

1.為什么要CommonJS規(guī)范

javascript存在的缺點(diǎn)

沒有模塊系統(tǒng)

標(biāo)準(zhǔn)庫(kù)比較少

沒有標(biāo)準(zhǔn)接口

缺乏包管理系統(tǒng)

CommonJS規(guī)范的提出,彌補(bǔ)了javascript沒有標(biāo)準(zhǔn)的缺陷,以達(dá)到像Python、Ruby、Java具備的開發(fā)大型應(yīng)用的基礎(chǔ)能力,這樣javascript不僅僅能在客戶端應(yīng)用還能開發(fā)以下應(yīng)用:

服務(wù)端應(yīng)用

命令行工具

桌面圖形界面應(yīng)用

混合應(yīng)用

2.CommonJS的模塊規(guī)范 1.模塊引入

使用require()來引入 ,接受一個(gè)模塊標(biāo)識(shí)。

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

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

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

在另一個(gè)文件require使用

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

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

4.Node模塊實(shí)現(xiàn)

Node中引入模塊需經(jīng)歷以下步驟:

路徑分析

文件定位

編譯執(zhí)行

Node中模塊分為兩類: 1.Node提供的 "核心模塊",2.用戶編寫的 "文件模塊"
核心模塊Node源碼編譯時(shí)已經(jīng)編譯成二進(jìn)制執(zhí)行文件,Node啟動(dòng)時(shí)直接加載進(jìn)內(nèi)存中,不需要文件定位和編譯執(zhí)行兩個(gè)步驟,且在路徑分析中優(yōu)先判斷,加載速度最快。

1.優(yōu)先從緩存加載

Node會(huì)對(duì)引入過的模塊進(jìn)行緩存,核心模塊和文件模塊相同的模塊在二次加載時(shí)一律從緩存優(yōu)先加載(第一優(yōu)先級(jí)),核心模塊緩存檢測(cè)優(yōu)先于文件模塊緩存檢測(cè)。

2.路徑分析文件定位
1.模塊標(biāo)識(shí)符分析

標(biāo)識(shí)符分類:

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

.或..開始的相對(duì)路徑文件模塊

以/開頭的絕對(duì)路徑模塊

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

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會(huì)逐個(gè)路徑嘗試知道找到目標(biāo)文件,模塊路徑越深耗時(shí)越多。

3.文件定位

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

3.模塊編譯

在Node中每個(gè)文件模塊都是一個(gè)對(duì)象。
編譯和執(zhí)行是引入文件模塊的最后一個(gè)階段,定位到一個(gè)文件后,Node會(huì)新建一個(gè)模塊對(duì)象,然后根據(jù)路徑載入并編譯。不同擴(kuò)展名載入方式:

.js 通過fs模塊讀取后編譯執(zhí)行

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

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

其他擴(kuò)展名文件 當(dāng)做.js文件載入

1.javascript模塊的編譯

在編譯過程中Node對(duì)獲取的javascript文件進(jìn)行的頭尾包裝

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

這樣每個(gè)模塊文件直接都進(jìn)行了作用域隔離,這就是Node對(duì)CommonJS規(guī)范的實(shí)現(xiàn)。

2.C/C++模塊編譯

Node調(diào)用process.dlopen()來進(jìn)行加載執(zhí)行,windows和*nix平臺(tái)下dlopen()通過不同方式實(shí)現(xiàn),通過libuv兼容層進(jìn)行封裝。

3.JSON文件編譯

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

4.核心模塊

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

依賴層關(guān)系: 內(nèi)建模塊(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++擴(kuò)展模塊
1.擴(kuò)展模塊在不同平臺(tái)上編譯和加載過程

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

2.編譯條件

node-gyp工具

V8引擎C++庫(kù)

libuv庫(kù)

Node內(nèi)部庫(kù)

其他庫(kù)

3.C/C++擴(kuò)展模塊的加載

require()引入.node文件過程

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

6.包與NPM

包結(jié)構(gòu):

package.json 包描述文件

bin 存放可執(zhí)行位二進(jìn)制文件

lib 存放javascript文件

doc 存放文檔

test 存放單元測(cè)試

7.前后端公用模塊
1.AMD規(guī)范

AMD規(guī)范是CommonJS規(guī)范的一個(gè)延伸,定義模塊方法:

define(id?, dependencies?, factory);

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

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

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

于AMD規(guī)范相比,CMD模塊更接近與Node對(duì)CommonJS規(guī)范的定義:

define(factory);

在依賴部分,CMD支持動(dòng)態(tài)引入:

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

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

兼容多種模塊規(guī)范

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

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107204.html

相關(guān)文章

  • Node.js 中度體驗(yàn)

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

    CastlePeaK 評(píng)論0 收藏0
  • 前端模塊化規(guī)范筆記

    摘要:目前通行的的模板規(guī)范共有兩種和的模塊系統(tǒng),是參照規(guī)范實(shí)現(xiàn)的即為服務(wù)器端模塊的規(guī)范。規(guī)范則是非同步加載模塊,允許指定回調(diào)函數(shù)。 目前通行的Javascript的模板規(guī)范共有兩種:CommonJS 和 AMD commonjs nodejs的模塊系統(tǒng),是參照commonjs規(guī)范實(shí)現(xiàn)的 commonjs即為服務(wù)器端模塊的規(guī)范。 commonjs的規(guī)范: 根據(jù)commonjs規(guī)范,一個(gè)單獨(dú)的...

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

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

    Java_oldboy 評(píng)論0 收藏0
  • Vue入坑筆記

    摘要:近段時(shí)間常使用開發(fā),寫點(diǎn)記錄,避免時(shí)間久之忘了。安裝教程查看是否已安裝,在中輸入若已安裝則輸出版本號(hào)。繼承報(bào)錯(cuò)可能是文件路徑問題。當(dāng)和繼承的不同時(shí)在文件夾內(nèi)外的話,會(huì)出現(xiàn)該錯(cuò)誤。 近段時(shí)間常使用vue-cli開發(fā),寫點(diǎn)記錄,避免時(shí)間久之忘了。 環(huán)境 1. nodejs  vue-cli開發(fā)基于nodejs環(huán)境,確保開發(fā)的環(huán)境中已安裝了nodejs?! “惭b教程 https://www....

    superw 評(píng)論0 收藏0
  • 零碎筆記:瀏覽器訪問一個(gè)網(wǎng)站所經(jīng)歷的步驟

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

    張金寶 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<