模塊化
目標:
能夠說出模塊化的好處
能夠知道CommonJS規定了哪些內容
能夠說出Node.js 中模塊的三大分類各自是什么
能夠使用npm 管理包
能夠了解什么是規范的包結構
能夠了解模塊的加載機制
1 模塊化的基本概念
1.1 什么是模塊化
模塊化是指,解決一個復雜問題時,自頂向下逐層把系統劃分成若干模塊的程序,對于整個系統來說,模塊是可組合、分解和更換的單元,
編程領域中的模塊化
編程領域中的模塊化,就是遵守固定的規則,把一個大檔案拆成獨立并互相依賴的多個小模塊,
把代碼進行模塊化拆分的好處:
提高了代碼的復用性
提高了代碼的可維護性
可以實作按需加載
1.2 模塊化規范
模塊化規范就是,對代碼進行模塊化的拆分與組合時,需要遵守的那些規則,
例如:
使用什么樣的語法格式來參考模塊
在模塊中使用什么樣的語法格式向外暴露成員
模塊化規范的好處:大家都遵守同樣的模塊化規范寫代碼,降低了溝通的成本,極大方便了各個模塊之間的相互呼叫,利人利己,
2 Node.js 中模塊化
2.1 Node.js 中模塊的分類
Node.js 中根據模塊來源的不同,將模塊分為了3大類,分別是:
- 內置模塊 (內置模塊是由Node.js官方提供的,例如fs、path、http 等)
- 自定義模塊(用戶創建的每個.js 檔案,都是自定義模塊)
- 第三方模塊(由第三方開發出來的模塊,并非官方提供的內置模塊,也不是用戶創建的自定義模塊,使用前需要先下載)
2.2 加載模塊
使用強大的require()方法,可以加載需要的內置模塊、用戶自定義模塊、第三方模塊進行使用,
例如;
// 1.加載內置的fs模塊
const fs = require('fs')
// 2.加載用戶的自定義模塊
const custom = require( './custom.js')
// 3.加載第三方模塊(關于第三方模塊的下載和使用,會在后面的課程中進行專門的講解)
const moment = require('moment')
注意:
- 使用require()方法加載其它模塊時,會執行被加載模塊中的代碼,
- 在使用require()加載用戶自定義模塊期間,可以省略.js 的后綴名,node 會自動補全,
2.3 node.js 中的模塊作用域
和函式作用域類似,在自定義模塊中定義的變數、方法等成員,只能在當前模塊內被訪問,這種模塊級別的訪問限制,叫做模塊作用域,
好處:防止了全域變數污染的問題
2.4 向外共享模塊作用域中的成員
1.module物件
在每個.js 自定義模塊中都有一個module 物件,它里面存盤了和當前模塊有關的資訊,
代碼:
console.log(module);
輸出的結果如下:

2.module.exports 物件
在自定義模塊中,可以使用 module.exports 物件,將模塊內的成員共享出去,供外界使用,
外界用require()方法匯入自定義模塊時,得到的就是 module.exports所指向的物件,
在一個自定義模塊中,默認情況下,module.exports 是個空物件,
// 向module. exports 物件上掛載 username屬性module.exports. username = 'zs'
// 向module . exports 物件上掛載 sayHello方法module.exports.sayHello = function() {
console.log( 'Hello! ')
}
3.exports物件
由于module.exports單詞寫起來比較復雜,為了簡化向外共享成員的代碼,Node 提供了exports 物件,默認情況下,exports 和module.exports 指向同一個物件,最終共享的結果,還是以module.exports 指向的物件為準,
// 1.向 module.exports 物件上掛載屬username
exports.username = 'zs'
// 2.向 module. exports物件上掛載方法sayHello
exports.sayHello = function() {
console.log( 'Hello!')
}
// 3.讓 module.exports指向一個全新的物件
// 外界匯入該模塊時,module.exports指向的就是這個新的物件,
exports = (
nickname: "小黑",sayti() {
console.log('Hi!')
}
}
4.共享成員時的注意點
使用require()方法匯入模塊時,匯入的結果,永遠以module.exports指向的物件為準,
// 1.向 module.exports 物件上掛載屬username
module.exports.username = 'zs'
// 2.向 module. exports物件上掛載方法sayHello
module.exports.sayHello = function() {
console.log( 'Hello!')
}
// 3.讓module.exports指向一個全新的物件
// 外界匯入該模塊時,module.exports指向的就是這個新的物件,
module.exports = (
nickname: "小黑",sayti() {
console.log('Hi!')
}
}
5.exports 和module.exports的使用誤區
時刻謹記,require()模塊時,得到的永遠是module.exports指向的物件:

2.5 Node.js 中的模塊化規范
Node.,js遵循了CommonJS模塊化規范,CommonJS規定了模塊的特性和各模塊之間如何相互依賴,
CommonJS 規定:
- 每個模塊內部,module 變數代表當前模塊,
- module變數是一個物件,它的 exports屬性(即 module.exports)是對外的介面,
- 加載某個模塊,其實是加載該模塊的 module.exports 屬性,require()方法用于加載模塊,
3 npm 與包
3.1包
1.什么是包
Node.js 中的第三方模塊又叫做包,
就像電腦和計算機指的是相同的東西,第三方模塊和包指的是同一個概念,只不過叫法不同,
2.包的來源
不同于Node.js 中的內置模塊與自定義模塊,包是由第三方個人或團隊開發出來的,免費供所有人使用,
注意:Node.,js 中的包都是免費且開源的,不需要付費即可免費下載使用,
3.為什么需要包
由于Node.js 的內置模塊僅提供了一些底層的API,導致在基于內置模塊進行專案開發的時,效率很低,
包是基于內置模塊封裝出來的,提供了更高級、更方便的 API,極大的提高了開發效率,
包和內置模塊之間的關系,類似于 jQuery和瀏覽器內置API之間的關系,
4.從哪里下載包
國外有一家IT公司,叫做npm, Inc.這家公司旗下有一個非常著名的網站: https://www.npmjs.com/,它是全球最大的包共享平臺,你可以從這個網站上搜索到任何你需要的包,只要你有足夠的耐心!
到目前位置,全球約1100多萬的開發人員,通過這個包共享平臺,開發并共享了超過120多萬個包供我們使用,
npm, Inc.公司提供了一個地址為https://registry.npmjs.org/的服務器,來對外共享所有的包,我們可以從這個服務器上下載自己所需要的包,
注意:
- 從https://www.npmjs.com/網站上搜索自己所需要的包
- 從https://registry.npmjs.org/服務器上下載自己需要的包
3.2 npm 初體驗
1.格式化時間的傳統做法
- 創建格式化時間的自定義模塊
- 定義格式化時間的方法
- 創建補零函式
- 從自定義模塊中匯出格式化時間的函式
- 匯入格式化時間的自定義模塊
- 呼叫格式化時間的函式
⒉格式化時間的高級做法
- 使用npm包管理工具,在專案中安裝格式化時間的包moment
- 使用require(匯入格式化時間的包
- 參考 moment的官方API檔案對時間進行格式化
3.在專案中安裝包的命令
如果想在專案中安裝指定名稱的包,需要運行如下的命令:
npm install 包的完整名稱
上述的裝包命令,可以簡寫成如下格式:
npm i 完整的包名稱
4.初次裝包后多了哪些檔案
初次裝包完成后,在專案檔案夾下多一個叫做node_modules 的檔案夾和package-lock.json 的組態檔,
node_modules檔案夾用來存放所有已安裝到專案中的包,require()匯入第三方包時,就是從這個目錄中查找并加載包,package-lockjson組態檔用來記錄node_modules目錄下的每一個包的下載資訊,例如包的名字、版本號、下載地址等,
注意:程式員不要手動修改node modules 或package-lockjson檔案中的任何代碼,npm包管理工具會自動維護它們,
5.安裝指定版本的包
默認情況下,使用npm install命令安裝包的時候,會自動安裝最新版本的包,如果需要安裝指定版本的包,可以在包名之后,通過**@符號**指定具體的版本,例如:
nmp i moment@2.22.2
6.包的語意化版本規范
包的版本號是以“點分十進制”形式進行定義的,總共有三位數字,例如2.24.0其中每一位數字所代表的的含義如下:
第1位數字:大版本 底層重構
第2位數字:功能版本
第3位數字:Bug修復版本
版本號提升的規則:只要前面的版本號增長了,則后面的版本號歸零,
3.3.3 包管理組態檔
npm規定,在專案根目錄中,必須提供一個叫做package.json 的包管理組態檔,用來記錄與專案有關的一些配置資訊,例如:
- 專案的名稱、版本號、描述等
- 專案中都用到了哪些包
- 哪些包只在開發期間會用到
- 那些包在開發和部署時都需要用到
1.多人協作的問題
遇到的問題:第三方包的體積過大,不方便團隊成員之間共亨專案源代碼,
解決方案:共享時剔除 node_modules
2.如何記錄專案中安裝了哪些包
在專案根目錄中,創建一個叫做 package.json 的組態檔,即可用來記錄專案中安裝了哪些包,從而方便剔除node_modules目錄之后,在團隊成員之間共亨專案的源代碼,
注意;今后在專案開發中,一定要把node modules檔案夾,添加到 .gitignore忽略檔案中,
3.快速創建package.json
npm包管理工具提供了一個快捷命令,可以在執行命令時所處的目錄中,快速創建 package.json 這個包管理組態檔:
作用:在執行命令所處的目錄中,快速新建package.json檔案
npm init -y
注意:
- 上述命令只能在英文的目錄下成功運行!所以,專案檔案夾的名稱一定要使用英文命名,不要使用中文,不能出現空格,
- 運行npm install 命令安裝包的時候,npm包管理工具會自動把包的名稱和版本號,記錄到package.json中,
4.dependencies節點
package.json檔案中,有一個dependencies節點,專門用來記錄您使用npm install命令安裝了哪些包,
5.一次性安裝所有包
當我們拿到一個剔除了 node_modules 的專案之后,需要先把所有的包下載到專案中,才能將專案運行起來,
否則會報類似于下面的錯誤:
- Error: Cannot find module " moment"
可以運行npm install命令(或npm i)一次性安裝所有的依賴包:
//執行npm install 命令時,npm 包管理工具會先讀取package.json 中的dependencies節點,
//讀取到記錄的所有依賴包名稱和版本號之后,npm包管理工具會把這些包一次性下載到專案中
npm install
6.卸載包
可以運行npm uninstall命令,來卸載指定的包:
//使用npm uninstall具體的包名來卸載包
npm uninstall moment
注意: npm uninstall 命令執行成功后,會把卸載的包,自動從 package.json 的dependencies 中移除掉,
7.devDependencies節點
如果某些包只在專案開發階段會用到,在專案上線之后不會用到,則建議把這些包記錄到 devDependencies節點中,
與之對應的,如果某些包在開發和專案上線之后都需要用到,則建議把這些包記錄到dependencies 節點中,
您可以使用如下的命令,將包記錄到devDependencies節點中:
// 安裝指定的包,并記錄到 devDependencies 節點中
npm i 包名 -D
// 注意:上述命令是簡寫形式,等價于下面完整的寫法:
npm install 包名 --save-dev
☆ 判斷是否放在devDependencies節點中,可以通過npm網站中的介紹,如下圖,有紅框標記部分的陳述句,則要放在devDependencies節點中,

3.3.4 解決下包速度慢的問題
1.下包速度慢的原因
在使用npm 下包的時候,默認從國外的 https://registry.npmjs.org/服務器進行下載,此時,網路資料的傳輸需要經過漫長的海底光纜,因此下包速度會很慢,
2.淘寶NPM鏡像服務器
淘寶在國內搭建了一個服務器,專門把國外官方服務器上的包同步到國內的服務器,然后在國內提供下包的服務,從而極大的提高了下包的速度,

擴展:
鏡像(Mirroring)是一種檔案存盤形式,一個磁盤上的資料在另一個磁捂上存在一個完全相同的副本即為鏡像,
3.切換npm的下包鏡像源
下包的鏡像源,指的就是下包的服務器地址
#查看當前的下包鏡像源
npm config get registry
#將下包的鏡像源切換為淘寶鏡像源
npm config set registry=https://registry.npm.taobao.org/
#檢查鏡像源是否下載成功
npm config get registry
4.nrm
為了更方便的切換下包的鏡像源,我們可以安裝 nrm 這個小工具,利用 nrm提供的終端命令,可以快速查看和切換下包的鏡像源,
#通過npm包管理器,將nrm安裝為全域可用的工具
npm i nrm -g
#查看所有可用的鏡像源
nrm ls
#將下包的鏡像源切換為taobao鏡像
nrm use taobao
3.3.5 包的分類
1.專案包
那些被安裝到專案的 node modules 目錄中的包,都是專案包,
專案包又分為兩類,分別是:
- 開發依賴包 (被記錄到devDependencies節點中的包,只在開發期間會用到)
- 核心依賴包(被記錄到dependencies 節點中的包,在開發期間和專案上線之后都會用到)
npm i 包名-D #開發依賴包(會被記錄到devDependencies節點下)
npm i 包名 #核心依賴包(會被記錄到 dependencies節點下)
2.全域包
在執行npm install命令時,如果提供了 -g 引數,則會把包安裝為全域包,
全域包會被安裝到C:\Users\用戶目錄\AppData\Roaming\npm\node_modules目錄下,
npm i 包名 -g #全域安裝指定的包
npm uninstall 包名 -g #卸載全域安裝的包
注意:
- 只有工具性質的包,才有全域安裝的必要性,因為它們提供了好用的終端命令,
- 判斷某個包是否需要全域安裝后才能使用,可以參考官方提供的使用說明即可,

3.i5ting_toc
i5ting_toc是一個可以把 md檔案轉為 html 頁面的小工具,使用步驟如下:
#將i5ting_ toc安裝為全域包
npm install -g i5ting_toc
#呼叫i5ting_toc,輕松實作md轉 html的功能
i5ting_toc -f 要轉換的md檔案路徑+檔案名 -o // -o代表轉換完成后自動打開轉換后的html頁面
3.3.6 規范的包結構
在清楚了包的概念、以及如何下載和使用包之后,接下來,我們深入了解一下包的內部結構,
一個規范的包,它的組成結構,必須符合以下3點要求:
- 包必須以單獨的目錄而存在
- 包的頂級目錄下要必須包含 package.json這個包管理組態檔
- package.json 中必須包含name、version、main這三個屬性,分別代表包的名字、版本號、包的入口,
注意:以上3點要求是一個規范的包結構必須遵守的格式,關于更多的約束,可以參考如下網址:
https://yarnpkg.com/zh-Hans/docs/package-json
3.3.7 開發屬于自己的包
439集待補
3.3.8 發布包
1.注冊npm賬號
- 訪問https://www.npmjs.com/網站,點擊 sign up 按鈕,進入注冊用戶界面
- 填寫賬號相關的資訊:Full Name、Public Email、Username、Password
- 點擊Create an Account按鈕,注冊賬號
- 登錄郵箱,點擊驗證鏈接,進行賬號的驗證
4 模塊的加載機制
4.1優先從快取中加載
模塊在第一次加載后會被快取,這也意味著多次呼叫require()不會導致模塊的代碼被執行多次,
注意:不論是內置模塊、用戶自定義模塊、還是第三方橫塊,它們都會優先從快取中加載,從而提高模塊的加載效率,
代碼:
1.js:
console.log('OK')
2.js
require('./1.js')
require('./1.js')
require('./1.js')
執行結果:只會輸出一遍OK
4.2 內置模塊的加載機制
內置模塊是由Node.js官方提供的模塊,內置模塊的加載優先級最高,
例如,require(‘fs’)始侄訓傳內置的 fs 模塊,即使在node_modules目錄下有名字相同的包也叫做fs,
4.3 自定義模塊的加載機制
使用require()加載自定義模塊時,必須指定以 ./ 或 ../ 開頭的路徑識別符號,在加載自定義模塊時,如果沒有指定./或../這樣的路徑識別符號,則node 會把它當作內置模塊或第三方模塊進行加載,
同時,在使用require()匯入自定義模塊時,如果省略了檔案的擴展名,則Node.js 會按順序分別嘗試加載以下的檔案:
- 按照確切的檔案名進行加載補全
- .js擴展名進行加載補全
- .json擴展名進行加載
- 補全.node 擴展名進行加載
- 加載失敗,終端報錯
4.4 第三方模塊的加載機制
如果傳遞給 require() 的模塊識別符號不是一個內置模塊,也沒有以 ./’或 ../開頭,則 Node.js 會從當前模塊的父目錄開始,嘗試從./node_modules 檔案夾中加載第三方模塊,
如果沒有找到對應的第三方模塊,則移動到再上一層父目錄中,進行加載,直到檔案系統的根目錄,
例如,假設在’C:\Users\itheima\project\foo.js’檔案里呼叫了require('tools'),則 Node,js 會按以下順序查找:
- C:\Users\itheima\project\node_modules\tools
- C:\Users\itheima\node_modules\itools
- C:\Users\node_modules\itools
- C:\node_modules\itools
4.5 目錄作為模塊
當把目錄作為模塊識別符號,傳遞給require()進行加載的時候,有三種加載方式:
- 在被加載的目錄下查找一個叫做
package.json的檔案,并尋找 main屬性,作為require()加載的入口 - 如果目錄里沒有package.ison檔案,或者main入口不存在或無法決議,則 Node.is 將會試圖加載目錄下的
index.js檔案 - 如果以上兩步都失敗了,則Node,js 會在終端列印錯誤訊息,報告模塊的缺失:
Error: Cannot find module 'xxx'
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/292364.html
標籤:其他
上一篇:JS 圖片切換
