npm(“Node 包管理器”)是 JavaScript 運行時 Node.js 的默認程序包管理器煌抒。[1]
npm 由兩個主要部分組成:
- 用于發(fā)布和下載程序包的 CLI(命令行界面)工具
- 托管 JavaScript 程序包的 在線存儲庫
為了更直觀地解釋囱怕,我們可以將存儲庫 npmjs.com 視為一個物流集散中心,該中心從賣方(npm 包裹的作者)那里接收貨物的包裹,并將這些貨物分發(fā)給買方(npm 包裹的用戶)瘫怜。
為了促進此過程扇售,npmjs.com 物流集散中心雇用了一群勤勞的袋熊(npm CLI),他們將被分配給每個 npmjs.com 用戶作為私人助理膝藕。 因此式廷,dependencies(依賴項)會如下傳遞給 JavaScript 開發(fā)人員:
發(fā)布 JS 軟件包的過程如下:
package.json
每個 JavaScript 項目(無論是 Node.js 還是瀏覽器應用程序)都可以被當作 npm 軟件包,并且通過 package.json 來描述項目和軟件包信息芭挽。
我們可以將 package.json 視為快遞盒子上的運輸信息滑废。
當運行 npm init
初始化 JavaScript/Node.js 項目時,將生成 package.json
文件袜爪,文件內的內容(基本元數(shù)據(jù))由開發(fā)人員提供:
-
name
:JavaScript 項目或庫的名稱蠕趁。 -
version
:項目的版本。通常辛馆,在應用程序開發(fā)中俺陋,由于沒有必要對開源庫進行版本控制,因此經(jīng)常忽略這一塊昙篙。但是倔韭,仍可以用它來定義版本。 -
description
:項目的描述瓢对。 -
license
:項目的許可證寿酌。
npm scripts
package.json
還支持一個 scripts
屬性,可以把它當作在項目本地運行的命令行工具硕蛹。例如醇疼,一個 npm 項目的 scripts
部分可能看起來像這樣:
{
"scripts": {
"build": "tsc",
"format": "prettier --write **/*.ts",
"format-check": "prettier --check **/*.ts",
"lint": "eslint src/**/*.ts",
"pack": "ncc build",
"test": "jest",
"all": "npm run build && npm run format && npm run lint && npm run pack && npm test"
}
}
eslint
,prettier
法焰,ncc
秧荆,jest
不是安裝為全局可執(zhí)行文件,而是安裝在項目本地的 node_modules/.bin/
中埃仪。
最新引入的 npx 使我們可以像在全局安裝程序一樣運行這些 node_modules
項目作用域命令乙濒,方法是在其前面加上 npx ...
(即npx prettier --write ** / *。ts
)。
package-lock.json
該文件描述了 npm JavaScript 項目中使用的依賴項的確切版本颁股。如果 package.json
是通用的描述性標簽么库,則 package-lock.json
是成分表。
就像我們通常不會讀取食品包裝袋上的成分表(除非你太無聊或需要知道)一樣甘有,package-lock.json
并不會被開發(fā)人員一行一行進行讀取诉儒。
package-lock.json
通常是由 npm install
命令生成的,也可以由我們的 NPM CLI 工具讀取亏掀,以確保使用 npm ci
復制項目的構建環(huán)境忱反。
dependencies vs devDependencies
devDependencies 里面的插件只用于開發(fā)環(huán)境,不用于生產(chǎn)環(huán)境滤愕,而 dependencies 是需要發(fā)布到生產(chǎn)環(huán)境的温算。[2]
這兩個以鍵值對象的形式出現(xiàn),其中 npm 庫的名稱為鍵间影,其語義格式版本為值米者。 大家可以看看 Github 的 TypeScript 操作模板中的示例:
{
"dependencies": {
"@actions/core": "^1.2.3",
"@actions/github": "^2.1.1"
},
"devDependencies": {
"@types/jest": "^25.1.4",
"@types/node": "^13.9.0",
"@typescript-eslint/parser": "^2.22.0",
"@zeit/ncc": "^0.21.1",
"eslint": "^6.8.0",
"eslint-plugin-github": "^3.4.1",
"eslint-plugin-jest": "^23.8.2",
"jest": "^25.1.0",
"jest-circus": "^25.1.0",
"js-yaml": "^3.13.1",
"prettier": "^1.19.1",
"ts-jest": "^25.2.1",
"typescript": "^3.8.3"
}
}
這些依賴通過帶有 --save
或 --save-dev
標志的 npm install
命令安裝。 它們分別用于生產(chǎn)和開發(fā)/測試環(huán)境宇智。 在下一節(jié)中蔓搞,我們將更深入地研究這些軟件包的安裝。
同時随橘,理解語義版本前面的符號非常重要(假設你已經(jīng)閱讀 semver 的 major.minor.patch
模型):
-
^
:表示最新的次版本喂分,例如,^1.0.4
可能會安裝主版本系列1
的最新次版本1.3.0
机蔗。 -
?
:表示最新的補丁程序版本蒲祈,與^
類似,?1.0.4
可能會安裝次版本系列1.0
的最新次版本1.0.7
萝嘁。
所有這些確切的軟件包版本都將記錄在 package-lock.json
文件中梆掸。
npm install
這是現(xiàn)在我們開發(fā) JavaScript/Node.js 應用程序時最常用的命令。
默認情況下牙言,npm install <package-name>
將安裝帶有 ^
版本號的軟件包的最新版本酸钦。npm 項目上下文中的 npm install
將根據(jù) package.json
規(guī)范將軟件包下載到項目的 node_modules
文件夾中,從而升級軟件包的版本(并重新生成 package-lock.json
)咱枉。 npm install <package-name>
可以基于 ^
和 ?
版本匹配卑硫。
如果要在全局上下文中安裝程序包,可以在機器的任何地方使用它蚕断,則可以指定全局標志 -g
(例如 live-server)欢伏。
npm i module_name -S = > npm install module_name --save 寫入到 dependencies 對象
npm i module_name -D => npm install module_name --save-dev 寫入到 devDependencies 對象
npm i module_name -g 全局安裝