亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > WEB開發 > 正文

CommonJS模塊規范與NodeJS的模塊系統底層原理

2024-04-27 15:17:32
字體:
來源:轉載
供稿:網友

原諒我標題黨 其實也沒有非常深入底層

在了解NodeJS模塊之前 首先來科普一下什么是CommonJS

CommonJS規范

它為javaScript制定一套規范——希望Javascript能在任何地方運行 使其具備開發大型應用的能力

出發點便是為了彌補當時JavaScript語言自身的缺點:

無模塊系統 現在ES6彌補了這個缺點沒有包管理胸痛 導致js應用沒有自加載和安裝依賴能力無標準接口 沒有定義過像Web服務器一類的標準統一接口標準庫太少 僅有部分核心庫,文件系統等常見需求沒有標準API;H5推進了這個過程,但也只是瀏覽器端

CommonJS-API寫出的應用可以跨宿主環境 這樣JavaScript就不僅僅只是停留在客戶端,他還可以開發:

服務器端JS應用命令行工具桌面圖形界面應用程序混合應用(原生應用內嵌瀏覽器)

CommonJS涵蓋一下內容

模塊I/O流二進制緩沖區套接字進程環境文件系統單元測試字符集編碼Web服務器網關接口包管理……

CommonJS模塊

為什么要介紹CommonJS 因為Node簡單易用的模塊系統就是借鑒了CommonJS的Modules規范 CommonJS模塊分為三部分:模塊引用、模塊定義、模塊標識

模塊導出

Node中,一個文件就是一個模塊 模塊中使用exports導出當前模塊的變量或函數 下面我就建立一個tool.js的工具模塊 并且通過exports導出

//tool.jsvar add = function add(a, b){ return a + b;}exPRots.add = add;

導出給外部的對象 就擁有一個add方法

不過要特別注意 如果直接給exports賦值為一個基本類型值不會成功 比如我們只是想單純的導出一個數字(雖然不會這么用)

exports = 123;

是完全不能夠導出的 至于為什么下面再說


我們一般不會直接通過exports這么用 在我們模塊的上下文中,還有一個module對象,引用我們模塊自身 而這個exports對象便是module上的屬性 我們通常的做法就是通過 module.exprots 導出

//tool.jsvar tool = { add: function (a, b){ return a + b; }}module.exprots = tool;

模塊引用

模塊引用很簡單 只需調用require()方法,接收一個模塊標識字符串作為參數 如此引入一個模塊到我們當前的環境中

var tool = require('./tool');

我們調用起來倒是輕松愉快 其實內部發生了日異月殊的變化(下面再說)

引入之后,我們就能調用內部的API了

tool.add(1, 2); //3

模塊標識

模塊標識就是我們傳遞給require()的那個字符串參數 這個字符串是符合小駝峰命名的字符串 或者是 . / .. 開頭的相對路徑,再或者絕對路徑 如果要引入的模塊后綴為 .js / .json / .node 可以省略

這種模塊機制導入容易,導出也容易 把類聚的方法和變量限定在私有作用域內 模塊之間空間獨立、互不干擾,好處不言而喻 媽媽再也不用擔心我們變量污染了

NodeJS模塊原理

NodeJS在CommonJS模塊規范基礎上作出了改動 在了解NodeJS模塊原理之前 先來了解一下NodeJS的模塊緩存機制

模塊緩存機制

NodeJS為了提高性能,我們引入模塊后,它都會進行緩存 這和我們在瀏覽器端的很像 但是瀏覽器緩存的是文件 而Node緩存編譯執行后的對象 我們可以做一個實驗

//increase.jsvar a = 0;var increase = function(){ ++a;}//index.jsvar increase = require('./increase');console.log(increase());console.log(increase());var add = require('./tool');console.log(increase());console.log(increase());

實驗的結果返回了 1 2 3 4 而不是 1 2 1 2 這就證明二次引用時實際引用了緩存的對象(編譯執行后的模塊)

所以當我們調用require( )方法時 Node會優先查看緩存(第一優先級),沒有緩存再進行一系列過程 這一系列過程就是:

路徑分析文件定位編譯執行

了解這些過程前 我們還要知道模塊分類

模塊種類

模塊大體上分兩種,它們還可以細分

核心模塊:Node提供的模塊 JavaScript核心模塊C/C++核心模塊文件模塊:用戶編寫的模塊 本地模塊:本地編寫模塊第三方模塊:從第三方下載的模塊

核心模塊在Node源碼編譯過程中,編譯進二進制執行文件 Node啟動,部分核心模塊被直接加載進內存 所以文件定位和編譯執行階段可省略,并且優先判斷路徑分析(加載最快)

文件模塊運行時動態加載,速度稍慢

模塊引入原理

路徑分析

路徑分析的優先級如下:

緩存加載核心模塊加載文件模塊加載

如果引入的是核心模塊,就直接填寫模塊名字符串就可以了

var http = require('http');

如果引入的是文件模塊,就會根據填入的路徑來定位文件

var tool = require('./tool');

我們下載的第三方模塊會存在于node_modules的文件夾 在分析它的時候 就會查找當前目錄下的node_modules中有沒有該文件 如果沒找到,就會查找父級目錄下有沒有node_modules并查找 以此類推 引用第三方模塊同樣不必輸入路徑

var react = require('react');

文件定位

require()分析標識符的時候,可能會出現省略文件擴展名的情況 此時,Node會按照 .js / .json / .node 的順序依次嘗試 很顯然這有一點兒性能問題,嘗試也需要時間 所以我們最好給 .json.node 形式的文件添加擴展名

如果我們定位到的是一個文件夾 Node會把它當做一個包來處理 根據包內部的package.json文件的main屬性繼續定位入口文件

關于包的概念,這里不講 可以暫時把它理解為擁有package.json配置文件的一個文件夾

模塊編譯

文件格式不同,載入方法也不同

.js文件:通過fs核心模塊同步讀取后編譯執行.node文件:C/C++擴展文件,通過dlopen()加載最后編譯生成的文件.json文件:通過fs核心模塊同步讀取后利用JSON.parse()解析其他:均當做.js文件處理

這里我只說一下JavaScript文件模塊的編譯 大家一定很奇怪一個問題 我們的文件中根本沒有什么exports,沒有什么require,它們從哪兒來的? 答案就在這里 就拿我們上面的模塊為例

//increase.jsvar a = 0;var increase = function(){ ++a;}

在這個編譯過程中,Node實際上對JS文件進行了包裝 加上了“龍頭鳳尾”(致敬兒時玩的四驅車) 龍頭:(function(exports, require, module, __filename, __dirname){/n 鳳尾:/n}); 封裝后的文件變成了這樣

(function(exports, require, module, __filename, __dirname){ var a = 0; var increase = function(){ ++a; }});

這回我們就可以理解為什么直接給exports賦基本類型值不可以 因為exports實際上作為形參傳入 賦值僅僅只是改變了形參


包裝后的代碼通過原生vm模塊的runInThisContext()執行(類似eval) 返回一個函數 最后將當前模塊的exports屬性、require方法等等傳入這個函數執行

==主頁傳送門==


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品国产亚洲精品2020| 欧美性猛交xxxx富婆| 欧美丰满老妇厨房牲生活| 久久99精品久久久久久琪琪| 欧美大成色www永久网站婷| 日韩禁在线播放| 97精品一区二区视频在线观看| 在线观看亚洲区| 国产日韩在线视频| 美女国内精品自产拍在线播放| 日韩免费av片在线观看| 日韩中文字幕不卡视频| 国产成人一区二区| 久久精品国产电影| 亚洲高清在线观看| 亚洲国产精彩中文乱码av| 国产精品入口免费视| 国产亚洲欧美日韩美女| 亚洲视频在线观看网站| 国产精品日韩久久久久| 亚洲最大福利网| 狠狠躁天天躁日日躁欧美| 中文字幕精品—区二区| 成人免费淫片视频软件| 欧美日韩亚洲一区二区| 免费91麻豆精品国产自产在线观看| 97视频在线观看网址| 国产精品久久视频| 91免费国产网站| 岛国av一区二区在线在线观看| 国模私拍一区二区三区| 91精品国产九九九久久久亚洲| 国产精品视频地址| 亚洲精品有码在线| 国产视频欧美视频| 一区二区欧美在线| 96sao精品视频在线观看| 欧美成人国产va精品日本一级| 成人免费视频在线观看超级碰| www.亚洲天堂| 96精品久久久久中文字幕| 久久久女人电视剧免费播放下载| 亚洲天堂成人在线| 韩国三级电影久久久久久| 亚洲日本成人女熟在线观看| 国产日韩欧美夫妻视频在线观看| 成人免费淫片视频软件| 欧美成人免费播放| 国产精品最新在线观看| 亚洲国产精品yw在线观看| 国内偷自视频区视频综合| 日本伊人精品一区二区三区介绍| 欧美激情一区二区三区在线视频观看| 亚洲男人第一网站| 视频在线一区二区| 一二美女精品欧洲| 成人福利网站在线观看11| 国内伊人久久久久久网站视频| 91亚洲一区精品| 亚洲综合av影视| 国产精品99久久久久久人| 日韩中文在线中文网在线观看| 亚洲免费成人av电影| 国产精品久久久久99| 亚洲最新av在线网站| 日本中文字幕成人| 91中文字幕在线观看| 伊人精品在线观看| 国产精品草莓在线免费观看| 国产极品精品在线观看| 中文字幕av一区中文字幕天堂| 国产成人精品av在线| 欧美另类精品xxxx孕妇| 2019日本中文字幕| 国产欧美日韩高清| 亚洲国产天堂久久综合网| 日韩成人在线免费观看| 国产精品美女无圣光视频| 国产精品日韩久久久久| 国产精品久久久久久久天堂| 日韩精品丝袜在线| 欧美精品性视频| 久久久久久av| 欧美黑人又粗大| 成人免费福利视频| 日日狠狠久久偷偷四色综合免费| 久久免费国产精品1| 日韩av免费一区| 原创国产精品91| 亚洲男人av在线| 久久久久五月天| 影音先锋欧美在线资源| 国产精品丝袜白浆摸在线| 国产成人激情视频| 中日韩午夜理伦电影免费| 色视频www在线播放国产成人| 久久91亚洲精品中文字幕| 亚洲精品在线观看www| 亚洲欧洲美洲在线综合| 日韩欧美中文免费| 欧美性资源免费| 91久久久久久久一区二区| 亚洲精品乱码久久久久久按摩观| 国产成人精品视频| 日韩欧美亚洲一二三区| 青青青国产精品一区二区| 欧美区二区三区| 亚洲乱亚洲乱妇无码| 成人免费观看49www在线观看| 成人在线播放av| 国产精品高潮呻吟久久av无限| 国产精品自产拍在线观看| 日韩av网址在线| 精品女同一区二区三区在线播放| 亚洲精品永久免费精品| 日韩电影中文 亚洲精品乱码| 国产91精品不卡视频| 欧美伦理91i| 亚洲精品国产精品乱码不99按摩| 国产精品免费电影| 久久久黄色av| 欧美日韩在线观看视频| 亚洲japanese制服美女| 亚洲男人天堂九九视频| 欧美人交a欧美精品| 亚洲国产精品免费| 国产视频丨精品|在线观看| 欧美体内谢she精2性欧美| 久久久久中文字幕| 国产精品久久久久久av| 欧美第一黄色网| 国产精品高清在线| 九九久久精品一区| 91夜夜未满十八勿入爽爽影院| 日韩有码片在线观看| 日韩成人av在线| 久久人人看视频| 日韩av在线资源| 不用播放器成人网| 国产精品久久久久久久久久| 91色中文字幕| 亚洲综合中文字幕在线| 久久69精品久久久久久久电影好| 久久久精品国产| 91精品国产沙发| 成人激情视频小说免费下载| 午夜美女久久久久爽久久| 精品国产一区二区三区久久| 日韩精品中文字幕视频在线| 国产日韩在线亚洲字幕中文| 欧美日韩在线视频一区二区| 欧美性视频精品| 日韩欧美在线一区| 精品久久久91| 91久久在线视频| 欧美性猛交99久久久久99按摩| 亚洲成av人乱码色午夜| 久久久综合av| 久久久免费在线观看| 中文字幕亚洲一区在线观看| 欧美激情视频一区| 国产精品18久久久久久首页狼| 欧美专区在线视频| 亚洲国产精品久久久久秋霞蜜臀|