帶你深入瞭解NPM——NPM初學者指南
前段時間,我們邀請了我們“城內”(葡萄城)資深開發工程師劉濤為大家分享了一次乾貨滿滿的關於Electron線上公開課,在課程過程中有不少同學對於NPM的概念和用法有一些疑問,所以這次我們希望通過這篇文章來解答各位同學的問題。另外在介紹的基礎上,我們還會適當的深入介紹下,如何在npm上釋出第一個屬於自己的包。那麼,讓我們馬上開始吧!
得益於Node.js的模組化生態系統,我們基本上可以把NPM認為是任何Node專案的基礎組成的一部分。但實際上,我們甚至可以說NPM是Node.js開發人員在開發者社群中最重要的工具之一。畢竟,他們每天都使用它來管理他們的專案使用的包。
但是,除了用它安裝軟體包外,大家是否真正深入瞭解過NPM呢?因此,我將嘗試介紹該工具的基礎知識,讓您更深入地瞭解並使用它,而不是僅僅瞭解npm install而已。
包管理
我們都知道你可以使用NPM安裝軟體包,但究竟是什麼意思呢?包基本上是包含您需要的程式碼的資料夾,您可以在本地或全域性安裝它。
本地安裝
本地安裝意味著您實際上將檔案下載到專案的資料夾中。在其中,您將找到一個您未建立的目錄,稱為“node_modules”。由於這種簡單的機制,這個本地資料夾可能會變得非常大。
那麼究竟這個資料夾有多大?一張圖來為你形容:
其實這只是個玩笑,通常你可以忽略該資料夾,讓Node.js為你處理它。
要執行本地安裝,您只需:
$ npm install [package-name]
您可以新增—save
字尾,Node會把包名稱和版本儲存到您的package.json
檔案中。請記住,這一點很重要(甚至至關重要),因為當你作為團隊中的一份子在工作時,你不會分發,也不會將node_modules資料夾新增到版本控制系統(無論是GIT,SVN還是你正在使用的任何版本管理系統),而只需簡單地分享package.json
檔案,然後讓你的隊友執行$npm install
命令,即可完成包的安裝和更新。這比共享整個資料夾更快,更容易維護,整個資料夾可以增長到包含千兆位元組的資料。
以下是一個package.json
檔案的結構:
{ |
|
"name": "Project name", |
|
"version": "1.0.0", |
|
"description": "This is a basic description", |
|
"main": "index.js", |
|
"scripts": { |
|
"test": "echo \"Error: no test specified\" && exit 1" |
|
}, |
|
"author": "Fernando Doglio", |
|
"license": "ISC", |
|
"dependencies": { |
|
"config": "^3.1.0", |
|
"express": "^4.17.1", |
|
"socket.io": "^2.2.0", |
|
"winston": "^3.2.1" |
|
} |
|
} |
|
您可能會改變一些,具體取決於您安裝的軟體包,或者您需要的檔案的哪些欄位(上面的示例中沒有使用的其他許多欄位)。
全域性安裝
您還可以全域性安裝軟體包,這意味著Node.js將能夠從您可能需要的任何專案中訪問它們。這樣做有什麼問題嗎?全域性安裝的包不會新增到package.json
檔案中,那麼既然不會新增到package.json中,那麼為什麼要安裝全域性安裝呢?
使用Node.js和NPM能做的一個很棒的原因之一就是構建人們通常稱之為“二進位制檔案”的東西,它們只是可以全域性安裝的指令碼,因此可以從盒子的任何位置訪問。這意味著您可以建立命令列工具並使用NPM來安裝它們!
例如:ExpressJS(Node.js最受歡迎的Web框架之一)或mocha(非常流行的測試庫)等軟體包也附帶了可以使用的可執行二進位制檔案。例如,mocha要求您在全域性和本地安裝它,以便擁有一個名為“mocha”的CLI工具,並能夠在本地專案上執行測試。
全域性包在需要新增到PATH環境變數的常規路徑中建立符號連結(或快捷方式)。
NPM的經典命令
install
命令只是您可以與NPM一起使用的眾多命令之一。事實上,拋開近60種不同的命令(是的,就這麼多!),我將簡要介紹一下,NPM還允許你建立自己的自定義命令,以防止內建命令對你不夠用。
以下是最常見的命令列表,取自官方文件:
- access:設定已釋出包的訪問級別,限制或啟用除作者之外的其他人的訪問許可權。例:
$ npm access public
- adduser:將使用者帳戶新增到登錄檔(預設情況下,登錄檔是npm的登錄檔,但您可以指定自定義帳戶)。例:
$ npm addUser
當提示時,將輸入使用者憑據(使用者名稱和密碼)及其電子郵件。 - audit:對已安裝的依賴項執行安全稽核,確保沒有已知的漏洞影響它們(以及擴充套件,您的專案)。您甚至可以使用該標誌
fix
自動修復在稽核期間可能發現的任何問題。 - bin:顯示當前專案的NPM bin資料夾。
- bugs:開啟新瀏覽器視窗中的錯誤列表。關於這個命令的有趣的一點是,它試圖猜測包的當前錯誤跟蹤器,一旦找到它,它就會啟動一個新的瀏覽器視窗。
- cache:雖然開發人員通常不會使用此命令,但它允許它們清除,驗證或向NPM的快取新增內容。在該快取中,儲存HTTP請求資訊和額外包資料。通常這是由NPM直接處理並且對開發人員透明地工作,但是如果你看到一些奇怪的行為,特別是當在不同的包和它們的不同版本之間切換時,嘗試清除快取可能是個好主意(只是為了開啟)安全的一面)。
- ci:幾乎與
npm install
用於自動化環境(例如持續整合過程)相同。此命令比此命令更嚴格,install
並確保安裝始終是乾淨的(如果存在,它會自動刪除node_modules資料夾)。 - completion:為npm及其子命令啟用Tab Completion。閱讀完整文件以獲取更多詳細資訊。
- config:允許您設定,獲取和編輯NPM的配置選項。
- dedupe:嘗試通過遍歷依賴關係樹並在儘可能遠的層次結構中移動重複的條目來減少依賴關係的重複。當您的應用程式開始增長幷包含越來越多的模組時,這尤其有用。使用此命令絕對是可選的,但如果您有很多依賴項,它將在安裝期間(在CI / CD環境中最有用)提供相當大的減少。
- deprecate:在庫的登錄檔中為特定版本(或版本範圍)新增棄用警告。
- dist-tag:幫助管理特定包的標籤。標籤可以充當版本別名,以幫助識別版本而無需記住數字。例如,預設情況下,最新標記用於所有庫的最後一個版本,您只需執行
npm install library-name@latest
,NPM將瞭解要下載的庫的哪個版本。 - docs:就像bug一樣,這個命令試圖猜測軟體包的官方文件在哪裡,並在本地瀏覽器中開啟該URL。
- doctor:執行一組預定義的檢查,以確保正在執行NPM的系統已準備好最低要求:
node
和git
命令是可訪問和可執行的,node_modules
資料夾(本地和全域性)可由NPM,登錄檔寫入或者它的任何自定義版本都是可訪問的,最後,NPM快取存在並且它正在工作。 - help-search / help: 幫助將顯示給定術語的文件頁面,如果沒有找到結果,help-search將對NPM的markdown幫助檔案執行全文搜尋並顯示相關結果列表。
- hook:允許您配置新的NPM掛鉤,當對感興趣的包進行更改時,它會通知自定義URL。例如,通過鍵入以下內容可以在釋出新版ExpressJS時收到通知:反過來,您可以使用該資訊執行任何您喜歡的操作(例如自動更新依賴項)。
$npm hook add express
http://your-url.com/new-express-version-endpoint - init:通過詢問一系列問題來幫助初始化專案,例如名稱,版本,作者等。最後,
package.json
使用該資訊建立一個全新的檔案。您還可以提供自定義初始化程式,以自定義處理到您的特定堆疊。 - install:安裝新包。您可以指定程式包的位置及其格式(即,您只能提供一個名稱,以便在主登錄檔中查詢它,或者在下載要安裝的程式包的tarball檔案的路徑中)。如果您不希望每次執行此命令時都安裝最新版本,則還可以指定要安裝的版本(對於自動環境(如CI / CD)尤其有用)。
- ls:列出當前專案的所有已安裝軟體包。您可以列出全域性包或本地安裝的包。在任何一種情況下,它不僅會列出
package.json
檔案中可見的名稱和版本,還會列出它們的依賴關係及其版本。 - outdated:檢查專案中過時的包。它將為您提供已安裝軟體包的報告,其當前版本,
package.json
檔案期望的版本以及主登錄檔中釋出的最新版本。 - owner:允許您管理包所有者。如果您是圖書館所有者或維護者,這一點很重要,但如果您僅限於使用包,則不是這樣。
- ping: ping當前配置的主npm登錄檔並測試身份驗證。這僅在您下載或安裝任何軟體包時遇到問題。它只會幫助您解決部分問題,但重要的是要記住它。
- prefix:顯示當前字首,換句話說,顯示最近資料夾中包含
package.json
檔案的路徑。您可以使用該-g
標誌,您將獲得安裝全域性包的實際位置。 - publish:允許開發人員通過使用組和組織公開或私下與他人共享模組。
這些是您可以使用的最常見或最有用的NPM命令,但是仍然有超過10個額外的命令供您檢視,因此我建議您將其文件新增為書籤,並做一個註釋以便返回並仔細檢查它!
如何釋出我自己的包
我要分享關於NPM知識的最後一點是與其他人分享你的工作是多麼容易。在上一個列表中,最後一個命令是釋出命令,它基本上允許你這樣做,但在這裡我想給你更多的細節。
準備專案的元資料
NPM的登錄檔本質上是一個巨大的包搜尋引擎,能夠同時託管所有內容,因此您不必同時索引它可以在您的工作中獲得的每一點元資料,以幫助其他人找到您的模組儘快。
換句話說,請確保您package.json
的設定正確。因為這些內容是吸引您(以及其他人)開始研究及分享您的包的主要因素。
- Name:這是列表中最明顯和最常見的,也是您在建立
package.json
檔案以跟蹤依賴關係時可能已經設定的名稱。請注意它的唯一性。 - Description:描述你的包,以便其他人可以快速瞭解他們在安裝時會得到什麼。並確保在描述中新增儘可能多的重要關鍵字,以便搜尋引擎知道如何快速找到您。這是嘗試找到您的軟體包的開發人員的需求與引擎首先嚐試正確索引的需求之間的平衡。
- Tags:這是一個以逗號分隔的關鍵字列表。話雖這麼說,一旦你開始釋出包,這些標籤就非常重要,因為在NPM的主站點上,它們可以作為你可以輕鬆瀏覽的類別。因此,如果您沒有完善你
package.json
中的標籤屬性,其他開發人員將很難通過分類導航找到你的包。 - Private:除非您只是自用,否則您需要儘快設定該屬性為
false
,否則沒有人能夠通過關鍵字搜尋找到您的模組。 - Bugs:這確保如果您在某個地方託管了您的內容,例如存在公共問題跟蹤的Github,則將此屬性設定為正確的URL。這將幫助NPM顯示連結並在包頁面上顯示當前開啟的問題的數量。
- Repository:不是嚴格要求的屬性,但是如果你新增它,NPM將能夠顯示額外的資訊,例如它的連結,活動,協作者列表,僅舉幾例。
- Homepage:與前一個一樣,它將幫助NPM顯示指向此URL的單獨連結(如果存在)。當您將程式碼放在一個URL(例如Github倉庫)和專用於另一個URL中的模組的特定網站時,這尤其重要。
- License:用於顯示您在專案中設定的實際許可證。如果您將其新增為
package.json
檔案的一部分,它將以不同且更突出的方式顯示。您也可以在readme.md上提及它,但在此處新增它將為NPM提供有關您的專案的額外知識。
通過提供我上面提到的元資料,NPM能夠展示這些資料並突出顯示它供開發人員檢視。以下示例為Winston的包頁面:
由於其團隊添加了元資料,添加了多少連結以及額外的位和詳細資訊。
一份優秀的文件
這步是可選的,但如果你的包是一個可供其他開發人員使用的模組的話,那麼我建議你最好提供一份優秀的文件,供他人蔘考。
因為你真的不能指望你的工具“上手簡單、易於理解”。NPM
的目的是為其他人提供一套幫助他們解決問題的預置工具。因此,請儘量豐富你的文件,吸引更多人來使用你的工具吧。
正式釋出包
編碼完成後,將有效的package.json
放置到你的目錄中,
並編寫儘可能完善的readme.md
檔案,您就可以釋出了。
要執行釋出操作,您必須做兩件事:
- 使用
npm
CLI 登入您的NPM帳戶(如果您已經有了賬號)。 - 釋出您的程式碼。
也就是隻需兩步,就能簡單的完成釋出。登陸:
$ npm login
將提示您輸入憑據,一旦您成功登入,您可以再輸入:
$ npm publish
請在專案的資料夾中執行此操作,否則第二個命令將失敗。
另外,請記住,包的名稱將由您的package.json檔案中的name屬性給出,而不是來自資料夾的名稱(通常二者都是相同的,但並這不意味著他倆有什麼關係)。因此,如果您遇到重複的名稱錯誤(考慮到NPM中已經有重名的包了),那麼您就必須進行更改一個再次釋出了。
結論
感謝閱讀,我希望到現在為止,你已經瞭解了NPM的複雜性和美感。它不僅僅是一個安裝軟體包的簡單工具,但如果你花時間檢查文件,你可以用它做更多的事