網(wǎng)站建設(shè)維護(hù)協(xié)議中山網(wǎng)站seo
1. 模塊化的基本概念
1.1 什么是模塊化
模塊化是指解決一個(gè)復(fù)雜問(wèn)題時(shí),自頂向下逐層把系統(tǒng)劃分成若干模塊的過(guò)程。對(duì)于整個(gè)系統(tǒng)來(lái)說(shuō),模塊是可組 合、分解和更換的單元。
1. 現(xiàn)實(shí)生活中的模塊化
2.編程領(lǐng)域中的模塊化
編程領(lǐng)域中的模塊化,就是遵守固定的規(guī)則,把一個(gè)大文件拆成獨(dú)立并互相依賴(lài)的多個(gè)小模塊。
把代碼進(jìn)行模塊化拆分的好處:
① 提高了代碼的復(fù)用性
② 提高了代碼的可維護(hù)性
1.2 模塊化規(guī)范
模塊化規(guī)范就是對(duì)代碼進(jìn)行模塊化的拆分與組合時(shí),需要遵守的那些規(guī)則。
例如:
- 使用什么樣的語(yǔ)法格式來(lái)引用模塊
- 在模塊中使用什么樣的語(yǔ)法格式向外暴露成員
模塊化規(guī)范的好處:大家都遵守同樣的模塊化規(guī)范寫(xiě)代碼,降低了溝通的成本,極大方便了各個(gè)模塊之間的相互調(diào)用, 利人利己。
2. Node.js 中的模塊化
2.1 Node.js 中模塊的分類(lèi)
Node.js 中根據(jù)模塊來(lái)源的不同,將模塊分為了 3 大類(lèi),分別是:
- 內(nèi)置模塊(內(nèi)置模塊是由 Node.js 官方提供的,例如 fs、path、http 等)
- 自定義模塊(用戶(hù)創(chuàng)建的每個(gè) .js 文件,都是自定義模塊)
- 第三方模塊(由第三方開(kāi)發(fā)出來(lái)的模塊,并非官方提供的內(nèi)置模塊,也不是用戶(hù)創(chuàng)建的自定義模塊,使用前需要先下載)
2.2 加載模塊
使用強(qiáng)大的 require() 方法,可以加載需要的內(nèi)置模塊、用戶(hù)自定義模塊、第三方模塊進(jìn)行使用。例如:
// 1. 加載內(nèi)置的 fs 塊
const fs = require('fs')// 2. 加載用戶(hù)的自定義模塊
const custom = require('./custom.js')// 3. 加載第三方模塊(關(guān)于第三方模塊的下載和使用,會(huì)在后面的課程中進(jìn)行專(zhuān)門(mén)的講解)
const moment = require('moment')
注意:使用 require() 方法加載其它模塊時(shí),會(huì)執(zhí)行被加載模塊中的代碼。
2.3 Node.js 中的模塊作用域
1. 什么是模塊作用域
和函數(shù)作用域類(lèi)似,在自定義模塊中定義的變量、方法等成員,只能在當(dāng)前模塊內(nèi)被訪(fǎng)問(wèn),這種模塊級(jí)別的訪(fǎng)問(wèn)限制,叫做模塊作用域。
// 02.test.js
const custom = require('./01.custom')// 輸出 { } 空對(duì)象
// 在 02.test.js 模塊中,無(wú)法訪(fǎng)問(wèn)到 01.custom.js 模塊中的私有成員
console.log(custom)
// 01.custom.js// 1. 在模塊作用域中定義常量 username
const username = '張三'
// 2. 在模塊作用域中定義函數(shù) sayHello
function sayHello () {console.log('大家好! 我是' + username)
}
2. 模塊作用域的好處
防止了全局變量污染的問(wèn)題
2.4 向外共享模塊作用域中的成員
1. module 對(duì)象
在每個(gè) .js 自定義模塊中都有一個(gè) module 對(duì)象,它里面存儲(chǔ)了和當(dāng)前模塊有關(guān)的信息,打印如下:
2. module.exports 對(duì)象
在自定義模塊中,可以使用 module.exports 對(duì)象,將模塊內(nèi)的成員共享出去,供外界使用。
外界用 require() 方法導(dǎo)入自定義模塊時(shí),得到的就是 module.exports 所指向的對(duì)象。
3. 共享成員時(shí)的注意點(diǎn)
使用 require() 方法導(dǎo)入模塊時(shí),導(dǎo)入的結(jié)果,永遠(yuǎn)以 module.exports 指向的對(duì)象為準(zhǔn)。
4. exports 對(duì)象
由于 module.exports 單詞寫(xiě)起來(lái)比較復(fù)雜,為了簡(jiǎn)化向外共享成員的代碼,Node 提供了 exports 對(duì)象。默認(rèn)情況下,exports 和 module.exports 指向同一個(gè)對(duì)象。最終共享的結(jié)果,還是以 module.exports 指向的對(duì)象為準(zhǔn)。
4. exports 和 module.exports 的使用誤區(qū)
時(shí)刻謹(jǐn)記,require() 模塊時(shí),得到的永遠(yuǎn)是 module.exports 指向的對(duì)象:
注意:為了防止混亂,建議大家不要在同一個(gè)模塊中同時(shí)使用 exports 和 module.exports
2.5 Node.js 中的模塊化規(guī)范
Node.js 遵循了 CommonJS 模塊化規(guī)范,CommonJS 規(guī)定了模塊的特性和各模塊之間如何相互依賴(lài)。
CommonJS 規(guī)定:
① 每個(gè)模塊內(nèi)部,module 變量代表當(dāng)前模塊。
② module 變量是一個(gè)對(duì)象,它的 exports 屬性(即 module.exports)是對(duì)外的接口。
③ 加載某個(gè)模塊,其實(shí)是加載該模塊的 module.exports 屬性。require() 方法用于加載模塊。
3. npm與包
3.1 包
1. 什么是包
Node.js 中的第三方模塊又叫做包。
就像電腦和計(jì)算機(jī)指的是相同的東西,第三方模塊和包指的是同一個(gè)概念,只不過(guò)叫法不同。
2. 包的來(lái)源
不同于 Node.js 中的內(nèi)置模塊與自定義模塊,包是由第三方個(gè)人或團(tuán)隊(duì)開(kāi)發(fā)出來(lái)的,免費(fèi)供所有人使用。
注意:Node.js 中的包都是免費(fèi)且開(kāi)源的,不需要付費(fèi)即可免費(fèi)下載使用。
3. 為什么需要包
由于 Node.js 的內(nèi)置模塊僅提供了一些底層的 API,導(dǎo)致在基于內(nèi)置模塊進(jìn)行項(xiàng)目開(kāi)發(fā)的時(shí),效率很低。
包是基于內(nèi)置模塊封裝出來(lái)的,提供了更高級(jí)、更方便的 API,極大的提高了開(kāi)發(fā)效率。
包和內(nèi)置模塊之間的關(guān)系,類(lèi)似于 jQuery 和 瀏覽器內(nèi)置 API 之間的關(guān)系。
4. 從哪里下載包
國(guó)外有一家 IT 公司,叫做 npm, Inc. 這家公司旗下有一個(gè)非常著名的網(wǎng)站: https://www.npmjs.com/ ,它是全球最大的包共享平臺(tái),你可以從這個(gè)網(wǎng)站上搜索到任何你需要的包,只要你有足夠的耐心!
到目前位置,全球約 1100 多萬(wàn)的開(kāi)發(fā)人員,通過(guò)這個(gè)包共享平臺(tái),開(kāi)發(fā)并共享了超過(guò) 120 多萬(wàn)個(gè)包 供我們使用。
npm, Inc. 公司提供了一個(gè)地址為 https://registry.npmjs.org/ 的服務(wù)器,來(lái)對(duì)外共享所有的包,我們可以從這個(gè)服務(wù)器上下載自己所需要的包。
- 從 https://www.npmjs.com/ 網(wǎng)站上搜索自己所需要的包
- 從 https://registry.npmjs.org/ 服務(wù)器上下載自己需要的包
5. 如何下載包
npm, Inc. 公司提供了一個(gè)包管理工具,我們可以使用這個(gè)包管理工具,從 https://registry.npmjs.org/ 服務(wù)器把需要的包下載到本地使用。
這個(gè)包管理工具的名字叫做 Node Package Manager(簡(jiǎn)稱(chēng) npm 包管理工具),這個(gè)包管理工具隨著 Node.js 的安裝包一起被安裝到了用戶(hù)的電腦上。
大家可以在終端中執(zhí)行 npm -v 命令,來(lái)查看自己電腦上所安裝的 npm 包管理工具的版本號(hào):
3.2 npm 初體驗(yàn)
1. 格式化時(shí)間的傳統(tǒng)做法
2. 格式化時(shí)間的高級(jí)做法
① 使用 npm 包管理工具,在項(xiàng)目中安裝格式化時(shí)間的包 moment
② 使用 require() 導(dǎo)入格式化時(shí)間的包
③ 參考 moment 的官方 API 文檔對(duì)時(shí)間進(jìn)行格式化
3. 在項(xiàng)目中安裝包的命令
如果想在項(xiàng)目中安裝指定名稱(chēng)的包,需要運(yùn)行如下的命令:
npm install 包的完整名稱(chēng)
上述的裝包命令,可以簡(jiǎn)寫(xiě)成如下格式:
npm i 完整的包名稱(chēng)
4. 初次裝包后多了哪些文件
初次裝包完成后,在項(xiàng)目文件夾下多一個(gè)叫做 node_modules 的文件夾和 package-lock.json 的配置文件。
其中:
- node_modules 文件夾用來(lái)存放所有已安裝到項(xiàng)目中的包。require() 導(dǎo)入第三方包時(shí),就是從這個(gè)目錄中查找并加載包。
- package-lock.json 配置文件用來(lái)記錄 node_modules 目錄下的每一個(gè)包的下載信息,例如包的名字、版本號(hào)、下載地址等。
注意:程序員不要手動(dòng)修改 node_modules 或 package-lock.json 文件中的任何代碼,npm 包管理工具會(huì)自動(dòng)維護(hù)它們。
5. 安裝指定版本的包
默認(rèn)情況下,使用 npm install 命令安裝包的時(shí)候,會(huì)自動(dòng)安裝最新版本的包。如果需要安裝指定版本的包,可以在包名之后,通過(guò) @ 符號(hào)指定具體的版本,例如:
npm i moment@2 .22 .2
6. 包的語(yǔ)義化版本規(guī)范
包的版本號(hào)是以“點(diǎn)分十進(jìn)制”形式進(jìn)行定義的,總共有三位數(shù)字,例如 2.24.0
其中每一位數(shù)字所代表的的含義如下:
第1位數(shù)字:大版本
第2位數(shù)字:功能版本
第3位數(shù)字:Bug修復(fù)版本
版本號(hào)提升的規(guī)則:只要前面的版本號(hào)增長(zhǎng)了,則后面的版本號(hào)歸零。
3.3 包管理配置文件
npm 規(guī)定,在項(xiàng)目根目錄中,必須提供一個(gè)叫做 package.json 的包管理配置文件。用來(lái)記錄與項(xiàng)目有關(guān)的一些配置信息。例如:
- 項(xiàng)目的名稱(chēng)、版本號(hào)、描述等
- 項(xiàng)目中都用到了哪些包
- 哪些包只在開(kāi)發(fā)期間會(huì)用到
- 那些包在開(kāi)發(fā)和部署時(shí)都需要用到
1. 多人協(xié)作的問(wèn)題
2. 如何記錄項(xiàng)目中安裝了哪些包
在項(xiàng)目根目錄中,創(chuàng)建一個(gè)叫做 package.json 的配置文件,即可用來(lái)記錄項(xiàng)目中安裝了哪些包。從而方便剔除 node_modules 目錄之后,在團(tuán)隊(duì)成員之間共享項(xiàng)目的源代碼。
注意:今后在項(xiàng)目開(kāi)發(fā)中,一定要把 node_modules 文件夾,添加到 .gitignore 忽略文件中。
3. 快速創(chuàng)建 package.json
npm 包管理工具提供了一個(gè)快捷命令,可以在執(zhí)行命令時(shí)所處的目錄中,快速創(chuàng)建 package.json 這個(gè)包管理配置文件:
// 作用: 在執(zhí)行命令所處的目錄中,快速新建 package.json 文件
npm init -y
注意:
① 上述命令只能在英文的目錄下成功運(yùn)行!所以,項(xiàng)目文件夾的名稱(chēng)一定要使用英文命名,不要使用中文,不能出現(xiàn)空格。
② 運(yùn)行 npm install 命令安裝包的時(shí)候,npm 包管理工具會(huì)自動(dòng)把包的名稱(chēng)和版本號(hào),記錄到 package.json 中。
4. dependencies 節(jié)點(diǎn)
5. 一次性安裝所有的包
當(dāng)我們拿到一個(gè)剔除了 node_modules 的項(xiàng)目之后,需要先把所有的包下載到項(xiàng)目中,才能將項(xiàng)目運(yùn)行起來(lái)。
否則會(huì)報(bào)類(lèi)似于下面的錯(cuò)誤:
//由于項(xiàng)目運(yùn)行依賴(lài)于 moment 這個(gè)包,如果沒(méi)有提前安裝好這個(gè)包,就會(huì)報(bào)如下的錯(cuò)誤:
Error: Cannot find module 'moment'
可以運(yùn)行 npm install 命令(或 npm i)一次性安裝所有的依賴(lài)包:
// 執(zhí)行 npm install 命今時(shí),npm 包管理T具會(huì)先讀取 package.json 中的 dependencies 節(jié)點(diǎn),
// 讀取到記錄的所有依賴(lài)包名稱(chēng)和版本號(hào)之后,npm 包管理工具會(huì)把這些包一次性下載到項(xiàng)目中
npm install
6. 卸載包
可以運(yùn)行 npm uninstall 命令,來(lái)卸載指定的包:
// 使用 npm uninstall 具體的包名 來(lái)卸載包
npm uninstall moment
注意:npm uninstall 命令執(zhí)行成功后,會(huì)把卸載的包,自動(dòng)從 package.json 的 dependencies 中移除掉。
7. devDependencies 節(jié)點(diǎn)
如果某些包只在項(xiàng)目開(kāi)發(fā)階段會(huì)用到,在項(xiàng)目上線(xiàn)之后不會(huì)用到,則建議把這些包記錄到 devDependencies 節(jié)點(diǎn)中。
與之對(duì)應(yīng)的,如果某些包在開(kāi)發(fā)和項(xiàng)目上線(xiàn)之后都需要用到,則建議把這些包記錄到 dependencies 節(jié)點(diǎn)中。
您可以使用如下的命令,將包記錄到 devDependencies 節(jié)點(diǎn)中:
// 安裝指定的包,并記錄到 devDependencies 節(jié)點(diǎn)中
npm i 包名 -D
// 注意:上述命令是簡(jiǎn)寫(xiě)形式,等價(jià)于下面完整的與法
npm install 包名 --save-dev