Node.js采用的是CommonJs規(guī)范,在NodeJS中,一般將代碼合理拆分到不同的JS文件中政勃,每一個(gè)文件就是一個(gè)模塊,而文件路徑就是模塊名兼砖。 在編寫每個(gè)模塊時(shí)奸远,都有require、exports讽挟、module三個(gè)預(yù)先定義好的變量可供使用懒叛。
Node.js中模塊的分類:
- 核心模塊(已經(jīng)封裝好的內(nèi)置模塊);
- 自己定義的模塊耽梅;
- 第三方的模塊(npm下載下來(lái)的)薛窥;
1. require
require
函數(shù)用來(lái)在一個(gè)模塊中引入另外一個(gè)模塊。傳入一個(gè)模塊名眼姐,返回一個(gè)模塊導(dǎo)出對(duì)象诅迷。用法:let cc = require("模塊名")
,其中模塊名可以用絕對(duì)路徑也可以用相對(duì)路徑,模塊的后綴名.js可以省略众旗。例如:
let cc1 = require('./main.js')
let cc2 = require('home/src/main.js')
let cc3 = require('./main')
require()函數(shù)用兩個(gè)作用:
- 執(zhí)行導(dǎo)入的模塊中的代碼竟贯;
- 返回導(dǎo)入模塊中的接口對(duì)象屑那;
require
方法加載第三方包的原理機(jī)制:
-
require('第三方包名')
優(yōu)先在加載該包的模塊的同級(jí)目錄node_modules
中查找第三方包。
let template = require('art-template') //加載第三方包
找到該第三方包中的
package.json
文件持际,并且找到里面的main
屬性對(duì)應(yīng)的入口模塊沃琅,該入口模塊即為加載的第三方模塊。如果在要加載的第三方包中沒(méi)有找到
package.json
文件或者是package.json
文件中沒(méi)有main
屬性蜘欲,則默認(rèn)加載第三方包中的index.js
文件益眉。如果在加載第三方模塊的文件的同級(jí)目錄沒(méi)有找到
node_modules
文件夾,或者以上所有情況都沒(méi)有找到姥份,則會(huì)向上一級(jí)父級(jí)目錄下查找node_modules
文件夾郭脂,查找規(guī)則如上一致。如果一直找到該模塊的磁盤根路徑都沒(méi)有找到澈歉,則會(huì)報(bào)錯(cuò):
can not find module xxx
展鸡。
2. exports
exports
對(duì)象用來(lái)導(dǎo)出當(dāng)前模塊的公共方法或?qū)傩裕瑒e的模塊通過(guò)require
函數(shù)使用當(dāng)前模塊時(shí)得到的就是當(dāng)前模塊的exports
對(duì)象埃难。用法:exports.name
,name為導(dǎo)出的對(duì)象名。例子:
exports.add = function () {
let i = 0
console.log(++i)
}
導(dǎo)出一個(gè)add方法供其他模塊使用
其實(shí)exports類似于ES6中的export的用法涡尘,用來(lái)導(dǎo)出一個(gè)指定名字的對(duì)象忍弛。
3. module.exports
module.exports
用來(lái)導(dǎo)出一個(gè)默認(rèn)對(duì)象细疚,沒(méi)有指定對(duì)象名,常見于修改模塊的原始導(dǎo)出對(duì)象惠昔。比如原本模塊導(dǎo)出的是一個(gè)對(duì)象,我們可以通過(guò)module.exports修改為導(dǎo)出一個(gè)函數(shù)挑势。如下:
module.exports = function () {
console.log('hello world镇防!')
}
4. 模塊的初始化
一個(gè)模塊中的JS代碼僅在模塊第一次被使用時(shí)執(zhí)行一次,并且在使用的過(guò)程中進(jìn)行初始化潮饱,之后緩存起來(lái)便于后續(xù)繼續(xù)使用。
5. 主模塊
通過(guò)命令行參數(shù)傳遞給NodeJS以啟動(dòng)程序的模塊被稱為主模塊啦扬。主模塊負(fù)責(zé)調(diào)度組成整個(gè)程序的其它模塊完成工作。例如通過(guò)以下命令啟動(dòng)程序時(shí)瞄摊,main.js就是主模塊。
$ node main.js // 運(yùn)行main.js啟動(dòng)程序蹲嚣,main.js稱為主模塊
完整實(shí)例:
在項(xiàng)目中我們有個(gè)hello.js
文件说贝,里面定義了一個(gè)求和的函數(shù)
var a = 1;
function add () {
return ++a;
}
exports.add = add
我們?cè)陧?xiàng)目的主模塊 main.js
中引入hello.js
var add1 = require('./hello')
var add2 = require('./hello')
console.log(add1.add())
console.log(add2.add())
該程序運(yùn)行的結(jié)果如下:
$ node main.js
2
3
我們可以看到hello.js
并沒(méi)有別引入兩次而初始化兩次哗总,說(shuō)明模塊只會(huì)在執(zhí)行的過(guò)程中被初始化一次。
總結(jié)
- Node中每個(gè)模塊都有一個(gè)
module
對(duì)象谆趾,module
對(duì)象中的有一個(gè)exports
屬性為一個(gè)接口對(duì)象,我們需要把模塊之間公共的方法或?qū)傩話燧d在這個(gè)接口對(duì)象中叛本,方便其他的模塊使用這些公共的方法或?qū)傩浴?/li> - Node中每個(gè)模塊的最后沪蓬,都會(huì)
return: module.exports
来候。 - Node中每個(gè)模塊都會(huì)把
module.exports
指向的對(duì)象賦值給一個(gè)變量exports
营搅,也就是說(shuō):exports = module.exports
云挟。 -
module.exports = XXX
,表示當(dāng)前模塊導(dǎo)出一個(gè)單一成員转质,結(jié)果就是XXX。 - 如果需要導(dǎo)出多個(gè)成員時(shí)必須使用
exports.add = XXX; exports.foo = XXX;
或者使用module.exports.add = XXX; module.export.foo = XXX;
沸枯。