亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

詳解NodeJS模塊化

 更新時(shí)間:2021年06月15日 09:55:56   投稿:zhanglei  
簡單的說Node.js就是運(yùn)行在服務(wù)端的JavaScript。Node.js是一個(gè)基于Chrome JavaScript運(yùn)行時(shí)建立的一個(gè)平臺。Node.js是一個(gè)事件驅(qū)動(dòng)I/O服務(wù)端JavaScript環(huán)境,基于Google的V8引擎,V8引擎執(zhí)行Javascript的速度非常快,性能非常好

一、前言

我們知道,Node.js是基于CommonJS規(guī)范進(jìn)行模塊化管理的,模塊化是面對復(fù)雜的業(yè)務(wù)場景不可或缺的工具,或許你經(jīng)常使用它,但卻從沒有系統(tǒng)的了解過,所以今天我們來聊一聊Node.js模塊化你所需要知道的一些事兒,一探Node.js模塊化的面貌。

二、正文

在Node.js中,內(nèi)置了兩個(gè)模塊來進(jìn)行模塊化管理,這兩個(gè)模塊也是兩個(gè)我們非常熟悉的關(guān)鍵字:require和module。內(nèi)置意味著我們可以在全局范圍內(nèi)使用這兩個(gè)模塊,而無需像其他模塊一樣,需要先引用再使用。

無需 require('require') or require('module')

在Node.js中引用一個(gè)模塊并不是什么難事兒,很簡單:

const config = require('/path/to/file')

但實(shí)際上,這句簡單的代碼執(zhí)行了一共五個(gè)步驟:

了解這五個(gè)步驟有助于我們了解Node.js模塊化的基本原理,也能讓我們甄別一些陷阱,讓我們簡單概括下這五個(gè)步驟都做了什么:

  • Resolving:找到待引用的目標(biāo)模塊,并生成絕對路徑。
  • Loading:判斷待引用的模塊內(nèi)容是什么類型,它可能是.json文件、.js文件或者.node文件。
  • Wrapping:顧名思義,包裝被引用的模塊。通過包裝,讓模塊具有私有作用域。
  • Evaluating:被加載的模塊被真正的解析和處理執(zhí)行。
  • Caching:緩存模塊,這讓我們在引入相同模塊時(shí),不用再重復(fù)上述步驟。

有些同學(xué)看完這五個(gè)步驟可能已經(jīng)心知肚明,對這些原理輕車熟路,有些同學(xué)心中可能產(chǎn)生了更多疑惑,無論如何,接下來的內(nèi)容會詳細(xì)解析上述的執(zhí)行步驟,希望能幫助大家答疑解惑 or 鞏固知識、查缺補(bǔ)漏。

By the way,如果有需要,可以和我一樣,構(gòu)建一個(gè)實(shí)驗(yàn)?zāi)夸?,跟著Demo進(jìn)行實(shí)驗(yàn)。

2.1、什么是模塊

想要了解模塊化,需要先直觀地看看模塊是什么。

我們知道在Node.js中,文件即模塊,剛剛提到了模塊可以是.js、.json或者.node文件,通過引用它們,可以獲取工具函數(shù)、變量、配置等等,但是它的具體結(jié)構(gòu)是怎樣呢?在命令行中簡單執(zhí)行下面的命令就可以看到模塊,也就是module對象的結(jié)構(gòu):

~/learn-node $ node

> module

Module {

  id: '<repl>',

  exports: {},

  parent: undefined,

  filename: null,

  loaded: false,

  children: [],

  paths: [ ... ] }

可以看到模塊也就是一個(gè)普通對象,只不過結(jié)構(gòu)中有幾個(gè)特殊的屬性值,需要我們一一去理解,有些屬性,例如id、parent、filename、children甚至都無需解釋,通過字面意思就可以理解。

后續(xù)的內(nèi)容會幫助大家理解這些字段的意義和作用。

2.2、Resolving

大致了解了什么是模塊后,我們從第一個(gè)步驟Resolving開始,了解模塊化原理,也就是Node.js如何尋找目標(biāo)模塊,并生成目標(biāo)模塊的絕對路徑。

那么什么我們剛剛要先打印module對象,先讓大家了解module的結(jié)構(gòu)呢?因?yàn)檫@里有兩個(gè)字段值id、paths和Resolving這個(gè)步驟息息相關(guān)。一起來看看吧。

首先是 id 屬性:

每個(gè)module都有id屬性,通常這個(gè)屬性值是模塊的完整路徑,通過這個(gè)值Node.js可以標(biāo)識和定位模塊的所在位置。但是在這兒并沒有具體的模塊,我們只是在命令行中輸出了module的結(jié)構(gòu),所以為默認(rèn)的<repl>值(repl表示交互式解釋器)。

其次是paths屬性:

這個(gè)paths屬性有什么作用呢?Node.js允許我們用多種方式來引用模塊,比如相對路徑、絕對路徑、預(yù)置路徑(馬上會解釋),假設(shè)我們需要引用一個(gè)叫做find-me的模塊,require如何幫助我們找到這個(gè)模塊呢?

require('find-me')

我們先打印看看paths中是什么內(nèi)容:

~/learn-node $ node
> module.paths
[ '/Users/samer/learn-node/repl/node_modules',
  '/Users/samer/learn-node/node_modules',
  '/Users/samer/node_modules',
  '/Users/node_modules',
  '/node_modules',
  '/Users/samer/.node_modules',
  '/Users/samer/.node_libraries',
  '/usr/local/Cellar/node/7.7.1/lib/node' ]
  

ok,其實(shí)就是一堆系統(tǒng)絕對路徑,這些路徑表示了所有目標(biāo)模塊可能出現(xiàn)的位置,并且它們是有序的,這意味著Node.js會按序查找paths中列出的所有路徑,如果找到這個(gè)模塊,就輸出該模塊的絕對路徑供后續(xù)使用。

現(xiàn)在我們知道Node.js會在這一堆目錄中查找module,嘗試執(zhí)行require('find-me')來查找find-me模塊,由于我們并沒有在任何目錄放置find-me模塊,所以Node.js在遍歷所有目錄之后并不能找到目標(biāo)模塊,因此報(bào)錯(cuò)Cannot find module 'find-me',這個(gè)錯(cuò)誤大家也許經(jīng)常看到:

~/learn-node $ node

> require('find-me')

Error: Cannot find module 'find-me'

    at Function.Module._resolveFilename (module.js:470:15)

    at Function.Module._load (module.js:418:25)

    at Module.require (module.js:498:17)

    at require (internal/module.js:20:19)

    at repl:1:1

    at ContextifyScript.Script.runInThisContext (vm.js:23:33)

    at REPLServer.defaultEval (repl.js:336:29)

    at bound (domain.js:280:14)

    at REPLServer.runBound [as eval] (domain.js:293:12)

    at REPLServer.onLine (repl.js:533:10)

現(xiàn)在,可以嘗試把需要引用的find-me模塊放在上述的任意一個(gè)目錄下,在這里我們創(chuàng)建一個(gè)node_modules目錄,并創(chuàng)建find-me.js文件,讓Node.js能夠找到它:

~/learn-node $ mkdir node_modules

~/learn-node $ echo "console.log('I am not lost');" > node_modules/find-me.js

~/learn-node $ node

> require('find-me');

I am not lost

{}

>

手動(dòng)創(chuàng)建了find-me.js文件后,Node.js果然找到了目標(biāo)模塊。當(dāng)然,當(dāng)Node.js本地的node_modules目錄中找到了find-me模塊,就不會再去后續(xù)的目錄中繼續(xù)尋找了。

有Node.js開發(fā)經(jīng)驗(yàn)的同學(xué)會發(fā)現(xiàn)在引用模塊時(shí),不一定非得指定到準(zhǔn)確的文件,也可以通過引用目錄來完成對目標(biāo)模塊的引用,例如:

~/learn-node $ mkdir -p node_modules/find-me

~/learn-node $ echo "console.log('Found again.');" > node_modules/find-me/index.js

~/learn-node $ node

> require('find-me');

Found again.

{}

>

find-me目錄下的index.js文件會被自動(dòng)引入。

當(dāng)然,這是有規(guī)則限制的,Node.js之所以能夠找到find-me目錄下的index.js文件,是因?yàn)槟J(rèn)的模塊引入規(guī)則是當(dāng)具體的文件名缺失時(shí)尋找index.js文件。我們也可以更改引入規(guī)則(通過修改package.json),比如把index -> main:

~/learn-node $ echo "console.log('I rule');" > node_modules/find-me/main.js

~/learn-node $ echo '{ "name": "find-me-folder", "main": "main.js" }' > node_modules/find-me/package.json

~/learn-node $ node

> require('find-me');

I rule

{}

>

2.3、require.resolve

如果你只想要在項(xiàng)目中引入某個(gè)模塊,而不想立即執(zhí)行它,可以使用require.resolve方法,它和require方法功能相似,只是并不會執(zhí)行被引入的模塊方法:

> require.resolve('find-me');

'/Users/samer/learn-node/node_modules/find-me/start.js'

> require.resolve('not-there');

Error: Cannot find module 'not-there'

    at Function.Module._resolveFilename (module.js:470:15)

    at Function.resolve (internal/module.js:27:19)

    at repl:1:9

    at ContextifyScript.Script.runInThisContext (vm.js:23:33)

    at REPLServer.defaultEval (repl.js:336:29)

    at bound (domain.js:280:14)

    at REPLServer.runBound [as eval] (domain.js:293:12)

    at REPLServer.onLine (repl.js:533:10)

    at emitOne (events.js:101:20)

    at REPLServer.emit (events.js:191:7)

>

可以看到,如果該模塊被找到了,Node.js會打印模塊的完整路徑,如果未找到,就報(bào)錯(cuò)。

了解了Node.js是如何尋找模塊之后,來看看Node.js是如何加載模塊的。

2.4、模塊間的父子依賴關(guān)系

我們把模塊間引用關(guān)系,表示為父子依賴關(guān)系。

簡單創(chuàng)建一個(gè)lib/util.js文件,添加一行console.log語句,標(biāo)識這是一個(gè)被引用的子模塊。

~/learn-node $ mkdir lib

~/learn-node $ echo "console.log('In util');" > lib/util.js

在index.js也輸入一行console.log語句,標(biāo)識這是一個(gè)父模塊,并引用剛剛創(chuàng)建的lib/util.js作為子模塊。

~/learn-node $ echo "require('./lib/util'); console.log('In index, parent', module);" > index.js

執(zhí)行index.js,看看它們間的依賴關(guān)系:

~/learn-node $ node index.js

In util

In index <ref *1> Module {

  id: '.',

  path: '/Users/samer/',

  exports: {},

  parent: null,

  filename: '/Users/samer/index.js',

  loaded: false,

  children: [

    Module {

      id: '/Users/samer/lib/util.js',

      path: '/Users/samer/lib',

      exports: {},

      parent: [Circular *1],

      filename: '/Users/samer/lib/util.js',

      loaded: true,

      children: [],

      paths: [Array]

    }

  ],

  paths: [...]

}

在這里我們關(guān)注與依賴關(guān)系相關(guān)的兩個(gè)屬性:children和parent。

在打印的結(jié)果中,children字段包含了被引入的util.js模塊,這表明了util.js是index.js所依賴的子模塊。

但仔細(xì)觀察util.js模塊的parent屬性,發(fā)現(xiàn)這里出現(xiàn)了Circular這個(gè)值,原因是當(dāng)我們打印模塊信息時(shí),產(chǎn)生了循環(huán)的依賴關(guān)系,在子模塊信息中打印父模塊信息,又要在父模塊信息中打印子模塊信息,所以Node.js簡單地將它處理標(biāo)記為Circular。

為什么需要了解父子依賴關(guān)系呢?因?yàn)檫@關(guān)系到Node.js是如何處理循環(huán)依賴關(guān)系的,后續(xù)會詳細(xì)描述。

在看循環(huán)依賴關(guān)系的處理問題之前,我們需要先了解兩個(gè)關(guān)鍵的概念:exports和module.exports。

2.5、exports, module.exports

exports:

exports是一個(gè)特殊的對象,它在Node.js中可以無需聲明,作為全局變量直接使用。它實(shí)際上是module.exports的引用,通過修改exports可以達(dá)到修改module.exports的目的。

exports也是剛剛打印的module結(jié)構(gòu)中的一個(gè)屬性值,但是剛剛打印出來的值都是空對象,因?yàn)槲覀儾]有在文件中對它進(jìn)行操作,現(xiàn)在我們可以嘗試簡單地為它賦值:

// 在lib/util.js的開頭新增一行
exports.id = 'lib/util';
  
// 在index.js的開頭新增一行
exports.id = 'index';

執(zhí)行index.js:

~/learn-node $ node index.js

In index Module {

  id: '.',

  exports: { id: 'index' },

  loaded: false,

  ... }

In util Module {

  id: '/Users/samer/learn-node/lib/util.js',

  exports: { id: 'lib/util' },

  parent:

   Module {

     id: '.',

     exports: { id: 'index' },

     loaded: false,

     ... },

  loaded: false,

  ... }

可以看到剛剛添加的兩個(gè)id屬性被成功添加到exports對象中。我們也可以添加除id以外的任意屬性,就像操作普通對象一樣,當(dāng)然也可以把exports變成一個(gè)function,例如:

exports = function() {}

module.exports:

module.exports對象其實(shí)就是我們最終通過require所得到的東西。我們在編寫一個(gè)模塊時(shí),最終給module.exports賦什么值,其他人引用該模塊時(shí)就能得到什么值。例如,結(jié)合剛剛對lib/util的操作:

const util = require('./lib/util');
  
console.log('UTIL:', util);
  
// 輸出結(jié)果
  
UTIL: { id: 'lib/util' }

由于我們剛剛通過exports對象為module.exports賦值{id: 'lib/util'},因此require的結(jié)果就相應(yīng)地發(fā)生了變化。

現(xiàn)在我們大致了解了exports和module.exports都是什么,但是有一個(gè)小細(xì)節(jié)需要注意,那就是Node.js的模塊加載是個(gè)同步的過程。

我們回過頭來看看module結(jié)構(gòu)中的loaded屬性,這個(gè)屬性標(biāo)識這個(gè)模塊是否被加載完成,通過這個(gè)屬性就能簡單驗(yàn)證Node.js模塊加載的同步性。

當(dāng)模塊被加載完成后,loaded值應(yīng)該為true。但到目前為止每次我們打印module時(shí),它的狀態(tài)都是false,這其實(shí)正是因?yàn)樵贜ode.js中,模塊的加載是同步的,當(dāng)我們還未完成加載的動(dòng)作(加載的動(dòng)作包括對module進(jìn)行標(biāo)記,包括標(biāo)記loaded屬性),因此打印出的結(jié)果就是默認(rèn)的loaded: false。

我們用setImmediate來幫助我們驗(yàn)證這個(gè)信息:

// In index.js
setImmediate(() => {
  console.log('The index.js module object is now loaded!', module)
});
點(diǎn)擊并拖拽以移動(dòng)
The index.js module object is now loaded! Module {
  id: '.',
  exports: [Function],
  parent: null,
  filename: '/Users/samer/learn-node/index.js',
  loaded: true,
  children:
   [ Module {
       id: '/Users/samer/learn-node/lib/util.js',
       exports: [Object],
       parent: [Circular],
       filename: '/Users/samer/learn-node/lib/util.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths:
   [ '/Users/samer/learn-node/node_modules',
     '/Users/samer/node_modules',
     '/Users/node_modules',
     '/node_modules' ] }

ok,由于console.log被后置到加載完成(打完標(biāo)記)之后,因此現(xiàn)在加載狀態(tài)變成了loaded: true。這充分驗(yàn)證了Node.js模塊加載是一個(gè)同步過程。

了解了exports、module.exports以及模塊加載的同步性后,來看看Node.js是如何處理模塊的循環(huán)依賴關(guān)系。

2.6、模塊循環(huán)依賴

在上述內(nèi)容中,我們了解到了模塊之間是存在父子依賴關(guān)系的,那如果模塊之間產(chǎn)生了循環(huán)的依賴關(guān)系,Node.js會怎么處理呢?假設(shè)有兩個(gè)模塊,分別為module1.js和modole2.js,并且它們互相引用了對方,如下:

// lib/module1.js
  
exports.a = 1;
  
require('./module2'); // 在這兒引用
  
exports.b = 2;
exports.c = 3;
  
// lib/module2.js
  
const Module1 = require('./module1');
console.log('Module1 is partially loaded here', Module1); // 引用module1并打印它

嘗試運(yùn)行module1.js,可以看到輸出結(jié)果:

~/learn-node $ node lib/module1.js

Module1 is partially loaded here { a: 1 }

結(jié)果中只輸出了{(lán)a: 1},而{b: 2, c: 3}卻不見了。仔細(xì)觀察module1.js,發(fā)現(xiàn)我們在module1.js的中間位置添加了對module2.js的引用,也就是exports.b = 2和exports.c = 3還未執(zhí)行之前的位置。如果我們把這個(gè)位置稱作發(fā)生循環(huán)依賴的位置,那么我們得到的結(jié)果就是在循環(huán)依賴發(fā)生前被導(dǎo)出的屬性,這也是基于我們上述驗(yàn)證過的Node.js的模塊加載是同步過程的結(jié)論。

Node.js就是這樣簡單地處理循環(huán)依賴。在加載模塊的過程中,會逐步構(gòu)建exports對象,為exports賦值。如果我們在模塊被完全加載前就引用這個(gè)模塊,那么我們只能得到部分的exports對象屬性。

2.7、.json和.node

在Node.js中,我們不僅能用require來引用JavaScript文件,還能用于引用JSON或C++插件(.json和.node文件)。我們甚至都不需要顯式地聲明對應(yīng)的文件后綴。

在命令行中也可以看到require所支持的文件類型:

~ % node

> require.extensions

[Object: null prototype] {

  '.js': [Function (anonymous)],

  '.json': [Function (anonymous)],

  '.node': [Function (anonymous)]

}

當(dāng)我們用require引用一個(gè)模塊,首先Node.js會去匹配是否有.js文件,如果沒有找到,再去匹配.json文件,如果還沒找到,最后再嘗試匹配.node文件。但是通常情況下,為了避免混淆和引用意圖不明,可以遵循在引用.json或.node文件時(shí)顯式地指定后綴,引用.js時(shí)省略后綴(可選,或都加上后綴)。

.json文件:

引用.json文件很常用,例如一些項(xiàng)目中的靜態(tài)配置,使用.json文件來存儲更便于管理,例如:

{
  "host": "localhost",
  "port": 8080
}

引用它或使用它都很簡單:

const { host, port } = require('./config');
console.log(`Server will run at http://${host}:${port}`)

輸出如下:

Server will run at http://localhost:8080

.node文件:

.node文件是由C++文件轉(zhuǎn)化而來,官網(wǎng)提供了一個(gè)簡單的由C++實(shí)現(xiàn)的hello插件,它暴露了一個(gè)hello()方法,輸出字符串world。有需要的話,可以跳轉(zhuǎn)鏈接做更多了解并進(jìn)行實(shí)驗(yàn)。

我們可以通過node-gyp來將.cc文件編譯和構(gòu)建成.node文件,過程也非常簡單,只需要配置一個(gè)binding.gyp文件即可。這里不詳細(xì)闡述,只需要知道生成.node文件后,就可以正常地引用該文件,并使用其中的方法。

例如,將hello()轉(zhuǎn)化生成addon.node文件后,引用并使用它:

const addon = require('./addon');
console.log(addon.hello());

2.8、Wrapping

其實(shí)在上述內(nèi)容中,我們闡述了在Node.js中引用一個(gè)模塊的前兩個(gè)步驟Resolving和Loading,它們分別解決了模塊的路徑和加載的問題。接下來看看Wrapping都做了什么。

Wrapping就是包裝,包裝的對象就是所有我們在模塊中寫的代碼。也就是我們引用模塊時(shí),其實(shí)經(jīng)歷了一層『透明』的包裝。

要了解這個(gè)包裝過程,首先要理解exports和module.exports之間的區(qū)別。

exports是對module.exports的引用,我們可以在模塊中使用exports來導(dǎo)出屬性,但是不能直接替換它。例如:

exports.id = 42; // ok,此時(shí)exports指向module.exports,相當(dāng)于修改了module.exports.
exports = { id: 42 }; // 無用,只是將它指向了{(lán) id: 42 }對象而已,對module.exports不會產(chǎn)生實(shí)際改變.
module.exports = { id: 42 }; // ok,直接操作module.exports.

大家也許會有疑惑,為什么這個(gè)exports對象似乎對每個(gè)模塊來說都是一個(gè)全局對象,但是它又能夠區(qū)分導(dǎo)出的對象是來自于哪個(gè)模塊,這是怎么做到的。

在了解包裝(Wrapping)過程之前,來看一個(gè)小例子:

// In a.js
var value = 'global'
  
// In b.js
console.log(value)  // 輸出:global
  
// In c.js
console.log(value)  // 輸出:global
  
// In index.html
...
<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script>

當(dāng)我們在a.js腳本中定義一個(gè)值value,這個(gè)值是全局可見的,后續(xù)引入的b.js和c.js都是可以訪問該value值。但是在Node.js模塊中卻并不是這樣,在一個(gè)模塊中定義的變量具有私有作用域,在其它模塊中無法直接訪問。這個(gè)私有作用域如何產(chǎn)生的?

答案很簡單,是因?yàn)樵诰幾g模塊之前,Node.js將模塊中的內(nèi)容包裝在了一個(gè)function中,通過函數(shù)作用域?qū)崿F(xiàn)了私有作用域。

通過require('module').wrapper可以打印出wrapper屬性:

~ $ node

> require('module').wrapper

[ '(function (exports, require, module, __filename, __dirname) { ',

  '\n});' ]

>

Node.js不會直接執(zhí)行文件中的任何代碼,但它會通過這個(gè)包裝后的function來執(zhí)行代碼,這讓我們的每個(gè)模塊都有了私有作用域,不會互相影響。

這個(gè)包裝函數(shù)有五個(gè)參數(shù):exports, require, module, __filename, __dirname。我們可以通過arguments參數(shù)直接訪問和打印這些參數(shù):

/learn-node $ echo "console.log(arguments)" > index.js

~/learn-node $ node index.js

{ '0': {},

  '1':

   { [Function: require]

     resolve: [Function: resolve],

     main:

      Module {

        id: '.',

        exports: {},

        parent: null,

        filename: '/Users/samer/index.js',

        loaded: false,

        children: [],

        paths: [Object] },

     extensions: { ... },

     cache: { '/Users/samer/index.js': [Object] } },

  '2':

   Module {

     id: '.',

     exports: {},

     parent: null,

     filename: '/Users/samer/index.js',

     loaded: false,

     children: [],

     paths: [ ... ] },

  '3': '/Users/samer/index.js',

  '4': '/Users/samer' }

簡單了解一下這幾個(gè)參數(shù),第一個(gè)參數(shù)exports初始時(shí)為空(未賦值),第二、三個(gè)參數(shù)require和module是和我們引用的模塊相關(guān)的實(shí)例,它們倆不是全局的。第四、五個(gè)參數(shù)__filename和__dirname分別表示了文件路徑和目錄。

整個(gè)包裝后的函數(shù)所做的事兒約等于:

unction (require, module, __filename, __dirname) {
  let exports = module.exports;
    
  // Your Code...
    
  return module.exports;
}

總而言之,wrapping就是將我們的模塊作用域私有化,以module.exports作為返回值將變量或方法暴露出來,以供使用。

2.9、Cache

緩存很容易理解,通過一個(gè)案例來看看吧:

echo 'console.log(`log something.`)' > index.js

// In node repl

> require('./index.js')

log something.

{}

> require('./index.js')

{}

>

可以看到,兩次引用同一個(gè)模塊,只打印了一次信息,這是因?yàn)榈诙我脮r(shí)取的是緩存,無需重新加載模塊。

打印require.cache可以看到當(dāng)前的緩存信息:

> require.cache

[Object: null prototype] {

  '/Users/samer/index.js': Module {

    id: '/Users/samer/index.js',

    path: '/Users/samer/',

    exports: {},

    parent: Module {

      id: '<repl>',

      path: '.',

      exports: {},

      parent: undefined,

      filename: null,

      loaded: false,

      children: [Array],

      paths: [Array]

    },

    filename: '/Users/samer/index.js',

    loaded: true,

    children: [],

    paths: [

      '/Users/samer/learn-node/repl/node_modules',

      '/Users/samer/learn-node/node_modules',

      '/Users/samer/node_modules',

      '/Users/node_modules',

      '/node_modules',

      '/Users/samer/.node_modules',

      '/Users/samer/.node_libraries',

      '/usr/local/Cellar/node/7.7.1/lib/node'

    ]

  }

}

可以看到剛剛引用的index.js文件處于緩存當(dāng)中,因此不會重新加載模塊。當(dāng)然我們也可以通過刪除require.cache來清空緩存內(nèi)容,達(dá)到重新加載的目的,這里不再演示。

三、總結(jié)

本文概述了使用Node.js模塊化時(shí)需要了解到的一些基本原理和常識,希望幫助大家對Node.js模塊化有更清晰的認(rèn)識。但更深入的細(xì)節(jié)并未在本文中闡述,例如wrapper函數(shù)內(nèi)部的處理邏輯,CommonJS的同步加載的問題、與ES模塊的區(qū)別等等。這些未提到的內(nèi)容大家可以在本文以外做更多探索。

以上就是詳解NodeJS模塊化的詳細(xì)內(nèi)容,更多關(guān)于NodeJS 模塊化的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 簡單實(shí)現(xiàn)node.js圖片上傳

    簡單實(shí)現(xiàn)node.js圖片上傳

    這篇文章主要為大家詳細(xì)介紹了node.js圖片上傳的簡單實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 關(guān)于Yarn的使用及說明

    關(guān)于Yarn的使用及說明

    這篇文章主要介紹了關(guān)于Yarn的使用及說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 詳解JWT與Token的應(yīng)用與原理

    詳解JWT與Token的應(yīng)用與原理

    這篇文章主要介紹了詳解JWT與Token的應(yīng)用與原理,JWT全稱“JSON Web Token”,是實(shí)現(xiàn)Token的機(jī)制,需要的朋友可以參考下
    2023-04-04
  • 如何使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序

    如何使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序

    NoSQL?數(shù)據(jù)庫對于處理大量分布式數(shù)據(jù)非常有用,我們可以在這個(gè)數(shù)據(jù)庫中存儲信息,對其進(jìn)行管理,這篇文章主要介紹了使用?Node.js?將?MongoDB?連接到您的應(yīng)用程序,需要的朋友可以參考下
    2022-09-09
  • nodeJS微信分享

    nodeJS微信分享

    這篇文章主要為大家詳細(xì)介紹了nodeJS微信分享的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Node.js中path模塊操作路徑的基本使用

    Node.js中path模塊操作路徑的基本使用

    這篇文章主要介紹了Node.js中path模塊操作路徑的基本使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • nodejs如何將多個(gè)目錄文件合并成一個(gè)

    nodejs如何將多個(gè)目錄文件合并成一個(gè)

    這篇文章主要介紹了nodejs如何將多個(gè)目錄文件合并成一個(gè)問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Nodejs使用Mongodb存儲與提供后端CRD服務(wù)詳解

    Nodejs使用Mongodb存儲與提供后端CRD服務(wù)詳解

    這篇文章主要給大家介紹了關(guān)于Nodejs使用Mongodb存儲與提供后端CRD服務(wù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • 配置node服務(wù)器并且鏈接微信公眾號接口配置步驟詳解

    配置node服務(wù)器并且鏈接微信公眾號接口配置步驟詳解

    這篇文章主要介紹了配置node服務(wù)器并且鏈接微信公眾號接口配置步驟詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,,需要的朋友可以參考下
    2019-06-06
  • nodejs微信掃碼支付功能實(shí)現(xiàn)

    nodejs微信掃碼支付功能實(shí)現(xiàn)

    本片文章通過代碼示例給大家詳細(xì)講述了如何用nodejs寫出微信掃碼支付這個(gè)功能,有興趣的朋友可以參考下。
    2018-02-02

最新評論