當前位置:
首頁 > 最新 > 2018 年了,你還是只會 npm install 嗎?

2018 年了,你還是只會 npm install 嗎?

GIF

作者:rianma | 騰訊web前端開發工程師

nodejs 社區乃至 Web 前端工程化領域發展到今天,作為 node 自帶的包管理工具的 npm 已經成為每個前端開發者必備的工具。但是現實狀況是,我們很多人對這個nodejs基礎設施的使用和了解還停留在: 會用這裡(一言不合就刪除整個 node_modules 目錄然後重新 install 這種事你沒做過嗎?)

當然 npm 能成為現在世界上最大規模的包管理系統,很大程度上確實歸功於它足夠用戶友好,你看即使我只會執行 install 也不必太擔心出什麼大岔子。但是 npm 的功能遠不止於 install 一下那麼簡單,這篇文章幫你扒一扒那些你可能不知道的 npm 原理、特性、技巧,以及(我認為的)最佳實踐。

你懶得讀的 npm 文檔,我幫你翻譯然後試驗整理過來了

npm init

我們都知道 package.json 文件是用來定義一個 package 的描述文件, 也知道命令用來初始化一個簡單的 package.json 文件,執行該命令後終端會依次詢問 name, version, description 等欄位。


而如果想要偷懶步免去一直按enter,在命令後追加 --yes 參數即可,其作用與一路下一步相同。


npm init 命令的原理並不複雜,調用腳本,輸出一個初始化的 package.json 文件就是了。所以相應地,定製 npm init 命令的實現方式也很簡單,在 Home 目錄創建一個即可,該文件的 module.exports 即為 package.json 配置內容,需要獲取用戶輸入時候,使用方法即可。

例如編寫這樣的 ~/.npm-init.js

此時在 ~/hello 目錄下執行將會得到這樣的 package.json:

除了生成 package.json, 因為 .npm-init.js 是一個常規的模塊,意味著我們可以執行隨便什麼 node 腳本可以執行的任務。例如通過 fs 創建 README, .eslintrc 等項目必需文件,實現項目腳手架的作用。

依賴包安裝

依賴管理是 npm 的核心功能,原理就是執行從 package.json 中的 dependencies, devDependencies 將依賴包安裝到當前目錄的 ./node_modules 文件夾中。


我們都知道要手動安裝一個包時,執行命令即可。這裡的第三個參數 package 通常就是我們所要安裝的包名,默認配置下 npm 會從默認的源 (Registry) 中查找該包名對應的包地址,並下載安裝。但在 npm 的世界裡,除了簡單的指定包名, package 還可以是一個指向有效包名的 http url/git url/文件夾路徑。

閱讀 npm的文檔, 我們會發現package 準確的定義,只要符合以下 a) 到 g) 其中之一條件,就是一個 package:


上面表格的定義意味著,我們在共享依賴包時,並不是非要將包發表到 npm 源上才可以提供給使用者來安裝。這對於私有的不方便 publish 到遠程源(即使是私有源),或者需要對某官方源進行改造,但依然需要把包共享出去的場景來說非常實用。

場景1: 本地模塊引用

nodejs 應用開發中不可避免有模塊間調用,例如在實踐中經常會把需要被頻繁引用的配置模塊放到應用根目錄;於是在創建了很多層級的目錄、文件後,很可能會遇到這樣的代碼:

除了看上去很醜以外,這樣的路徑引用也不利於代碼的重構。並且身為程序員的自我修養告訴我們,這樣重複的代碼多了也就意味著是時候把這個模塊分離出來供應用內其他模塊共享了。例如這個例子里的 config.js 非常適合封裝為 package 放到 node_modules 目錄下,共享給同應用內其他模塊。

無需手動拷貝文件或者創建軟鏈接到 node_modules 目錄,npm 有更優雅的解決方案。

方案:

創建 config 包:undefined新增 config 文件夾; 重命名 config.js 為 config/index.js 文件; 創建 package.json 定義 config 包{

"name": "config",

"main": "index.js",

"version": "0.1.0"

}

在應用層 package.json 文件中新增依賴項,然後執行; 或直接執行第 3 步{ "dependencies": {

"config": "file:./config"

}

}

(等價於第 2 步)直接在應用目錄執行

此時,查看 `node_modules` 目錄我們會發現多出來一個名為 `config`,指向上層 `config/` 文件夾的軟鏈接。這是因為 npm 識別 `file:` 協議的url,得知這個包需要直接從文件系統中獲取,會自動創建軟鏈接到 node_modules 中,完成「安裝」過程。

相比手動軟鏈,我們既不需要關心 windows 和 linux 命令差異,又可以顯式地將依賴信息固化到 dependencies 欄位中,開發團隊其他成員可以執行 `npm install` 後直接使用。

場景2:私有 git 共享 package

有些時候,我們一個團隊內會有一些代碼/公用庫需要在團隊內不同項目間共享,但可能由於包含了敏感內容,或者代碼太爛拿不出手等原因,不方便發布到源。

這種情況下,我們可以簡單地將被依賴的包託管在私有的 git 倉庫中,然後將該 git url 保存到 dependencies 中. npm 會直接調用系統的 git 命令從 git 倉庫拉取包的內容到 node_modules 中。

npm 支持的 git url 格式:

git 路徑後可以使用 # 指定特定的 git branch/commit/tag, 也可以 #semver: 指定特定的 semver range.

例如:

場景3: 開源 package 問題修復

使用某個 npm 包時發現它有某個嚴重bug,但也許最初作者已不再維護代碼了,也許我們工作緊急,沒有足夠的時間提 issue 給作者再慢慢等作者發布新的修復版本到 npm 源。

此時我們可以手動進入 node_modules 目錄下修改相應的包內容,也許修改了一行代碼就修復了問題。但是這種做法非常不明智!

首先 node_modules 本身不應該放進版本控制系統,對 node_modules 文件夾中內容的修改不會被記錄進 git 提交記錄;其次,就算我們非要反模式,把 node_modules 放進版本控制中,你的修改內容也很容易在下次 team 中某位成員執行或時被覆蓋,而這樣的一次提交很可能包含了幾十幾百個包的更新,你自己所做的修改很容易就被淹沒在龐大的 diff 文件列表中了。

方案:

最好的辦法應當是 fork 原作者的 git 庫,在自己所屬的 repo 下修復問題後,將 dependencies 中相應的依賴項更改為自己修復後版本的 git url 即可解決問題。(Fork 代碼庫後,也便於向原作者提交 PR 修復問題。上游代碼庫修復問題後,再次更新我們的依賴配置也不遲。)

npm install 如何工作


npm install 執行完畢後,我們可以在 node_modules 中看到所有依賴的包。雖然使用者無需關注這個目錄里的文件夾結構細節,只管在業務代碼中引用依賴包即可,但了解 node_modules 的內容可以幫我們更好理解 npm 如何工作,了解從 npm 2 到 npm 5 有哪些變化和改進。

為簡單起見,我們假設應用目錄為 app, 用兩個流行的包,作為依賴包做示例說明。並且為了正常安裝,使用了「上古」 npm 2 時期的版本,.


npm 2 在安裝依賴包時,採用簡單的遞歸安裝方法。執行後,npm 2 依次遞歸安裝和兩個包到 node_modules 中。執行完畢後,我們會看到 ./node_modules 這層目錄只含有這兩個子目錄。

進入更深一層 nconf 或 webpack 目錄,將看到這兩個包各自的 node_modules 中,已經由 npm 遞歸地安裝好自身的依賴包。包括,等等。而每一個包都有自己的依賴包,每個包自己的依賴都安裝在了自己的 node_modules 中。依賴關係層層遞進,構成了一整個依賴樹,這個依賴樹與文件系統中的文件結構樹剛好層層對應。

最方便的查看依賴樹的方式是直接在 app 目錄下執行命令。

這樣的目錄結構優點在於層級結構明顯,便於進行傻瓜式的管理:

例如新裝一個依賴包,可以立即在第一層 node_modules 中看到子目錄

在已知所需包名和版本號時,甚至可以從別的文件夾手動拷貝需要的包到 node_modules 文件夾中,再手動修改 package.json 中的依賴配置

要刪除這個包,也可以簡單地手動刪除這個包的子目錄,並刪除 package.json 文件中相應的一行即可

實際上,很多人在 npm 2 時代也的確都這麼實踐過,的確也都可以安裝和刪除成功,並不會導致什麼差錯。

但這樣的文件結構也有很明顯的問題:

對複雜的工程, node_modules 內目錄結構可能會太深,導致深層的文件路徑過長而觸發 windows 文件系統中,文件路徑不能超過 260 個字元長的錯誤

部分被多個包所依賴的包,很可能在應用 node_modules 目錄中的很多地方被重複安裝。隨著工程規模越來越大,依賴樹越來越複雜,這樣的包情況會越來越多,造成大量的冗餘。

——在我們的示例中就有這個問題,和都依賴這個包,所以在文件系統中,webpack 和 nconf 的 node_modules 子目錄中都安裝了相同的 async 包,並且是相同的版本。


主要為了解決以上問題,npm 3 的 node_modules 目錄改成了更加扁平狀的層級結構。文件系統中,,的層級關係變成了平級關係,處於同一級目錄中。

雖然這樣一來 webpack/node_modules 和 nconf/node_modules 中都不再有 async 文件夾,但得益於 node 的模塊載入機制,他們都可以在上一級 node_modules 目錄中找到 async 庫。所以 webpack 和 nconf 的庫代碼中語句的執行都不會有任何問題。

這只是最簡單的例子,實際的工程項目中,依賴樹不可避免地會有很多層級,很多依賴包,其中會有很多同名但版本不同的包存在於不同的依賴層級,對這些複雜的情況, npm 3 都會在安裝時遍歷整個依賴樹,計算出最合理的文件夾安裝方式,使得所有被重複依賴的包都可以去重安裝。

npm 文檔提供了更直觀的例子解釋這種情況:

這裡之所以 D 也安裝到了與 B C 同一級目錄,是因為 npm 會默認會在無衝突的前提下,儘可能將包安裝到較高的層級。

如果是,,的依賴關係,得到的安裝後結構是:

這裡是因為,對於 npm 來說同名但不同版本的包是兩個獨立的包,而同層不能有兩個同名子目錄,所以其中的 D@2 放到了 C 的子目錄而另一個 D@1 被放到了再上一層目錄。

很明顯在 npm 3 之後 npm 的依賴樹結構不再與文件夾層級一一對應了。想要查看 app 的直接依賴項,要通過命令指定參數來查看:

PS: 與本地依賴包不同,如果我們通過全局安裝包到全局目錄時,得到的目錄依然是「傳統的」目錄結構。而如果使用 npm 3 想要得到「傳統」形式的本地 node_modules 目錄,使用命令即可。


npm 5 發佈於 2017 年也是目前最新的 npm 版本,這一版本依然沿用 npm 3 之後扁平化的依賴包安裝方式,此外最大的變化是增加了文件。

package-lock.json 的作用是鎖定依賴安裝結構,如果查看這個 json 的結構,會發現與 node_modules 目錄的文件層級結構是一一對應的。

以依賴關係為:的 "app" 項目為例, 其 package-lock 文件包含了這樣的片段。

看懂 package-lock 文件並不難,其結構是同樣類型的幾個欄位嵌套起來的,主要是,,,,這幾個欄位而已。

,,用來記錄包的準確版本號、內容hash、安裝源的,決定了要安裝的包的準確「身份」信息

假設蓋住其他欄位,只關注文件中的我們會發現,整個文件的 JSON 配置里的 dependencies 層次結構與文件系統中 node_modules 的文件夾層次結構是完全對照的

只關注欄位又會發現,除最外層的屬性為 true 以外, 其他層的 requires 屬性都對應著這個包的 package.json 里記錄的自己的依賴項

因為這個文件記錄了 node_modules 里所有包的結構、層級和版本號甚至安裝源,它也就事實上提供了 「保存」 node_modules 狀態的能力。只要有這樣一個 lock 文件,不管在那一台機器上執行 npm install 都會得到完全相同的 node_modules 結果。

這就是 package-lock 文件致力於優化的場景:在從前僅僅用 package.json 記錄依賴,由於 semver range 的機制;一個月前由 A 生成的 package.json 文件,B 在一個月後根據它執行 npm install 所得到的 node_modules 結果很可能許多包都存在不同的差異,雖然 semver 機制的限制使得同一份 package.json 不會得到大版本不同的依賴包,但同一份代碼在不同環境安裝出不同的依賴包,依然是可能導致意外的潛在因素。

相同作用的文件在 npm 5 之前就有,稱為 npm shrinkwrap 文件,二者作用完全相同,不同的是後者需要手動生成,而 npm 5 默認會在執行 npm install 後就生成 package-lock 文件,並且建議你提交到 git/svn 代碼庫中。

package-lock.json 文件在最初 npm 5.0 默認引入時也引起了相當大的爭議。在 npm 5.0 中,如果已有 package-lock 文件存在,若手動在 package.json 文件新增一條依賴,再執行 npm install, 新增的依賴並不會被安裝到 node_modules 中, package-lock.json 也不會做相應的更新。這樣的表現與使用者的自然期望表現不符。在 npm 5.1 的首個 Release 版本中這個問題得以修復。這個事情告訴我們,要升級,不要使用 5.0。

——但依然有反對的聲音認為 package-lock 太複雜,對此 npm 也提供了禁用配置:

依賴包版本管理

依賴包安裝完並不意味著就萬事大吉了,版本的維護和更新也很重要。這一章介紹依賴包升級管理相關知識,太長不看版本請直接跳到 4.3 最佳實踐


npm 依賴管理的一個重要特性是採用了語義化版本 (semver) 規範,作為依賴版本管理方案。

semver 約定一個包的版本號必須包含3個數字,格式必須為, 意為.

MAJOR 對應大的版本號迭代,做了不兼容舊版的修改時要更新 MAJOR 版本號

MINOR 對應小版本迭代,發生兼容舊版API的修改或功能更新時,更新MINOR版本號

PATCH 對應修訂版本號,一般針對修復 BUG 的版本號

對於包作者(發布者),npm 要求在 publish 之前,必須更新版本號。npm 提供了工具,執行可以簡單地將版本號中相應的數字加1.

如果包是一個 git 倉庫,還會自動創建一條注釋為更新後版本號的 git commit 和名為該版本號的 tag

對於包的引用者來說,我們需要在 dependencies 中使用 semver 約定的 semver range 指定所需依賴包的版本號或版本範圍。npm 提供了網站 https://semver.npmjs.com 可方便地計算所輸入的表達式的匹配範圍。常用的規則示例如下表:

任意兩條規則,通過連接起來,則表示兩條規則的並集:

如可以匹配:

*`2.3.1`,`2,8.1`,`3.3.1`*但不匹配`1.0.0`,`2.2.0`,`3.1.0`,`4.0.0`

PS: 除了這幾種,還有如下更直觀的表示版本號範圍的寫法:

或匹配所有主版本

或匹配 主版本號為 1 的所有版本

或匹配 版本號為 1.2 開頭的所有版本

PPS: 在常規僅包含數字的版本號之外,semver 還允許在後追加後跟點號分隔的標籤,作為預發布版本標籤 - Prerelese Tags,通常被視為不穩定、不建議生產使用的版本。例如:

上表中我們最常見的是這種格式的 range, 因為我們在使用安裝包時,npm 默認安裝當前最新版本,例如, 然後在所安裝的版本號前加號, 將寫入 package.json 依賴配置,意味著可以匹配 1.8.11 以上,2.0.0 以下的所有版本。


問題來了,在安裝完一個依賴包之後有新版本發布了,如何使用 npm 進行版本升級呢?——答案是簡單的或,但在不同的 npm 版本,不同的 package.json, package-lock.json 文件,安裝/升級的表現也不同。

我們不妨還以 webpack 舉例,做如下的前提假設:

我們的工程項目依賴 webpack

項目最初初始化時,安裝了當時最新的包 webpack@1.8.0,並且 package.json 中的依賴配置為:

當前(2018年3月) webpack 最新版本為, webpack 1.x 最新子版本為

如果我們使用的是 npm 3, 並且項目不含 package-lock.json, 那麼根據 node_modules 是否為空,執行 install/update 的結果如下 (node 6.13.1, npm 3.10.10環境下試驗):

根據這個表我們可以對 npm 3 得出以下結論:

如果本地 node_modules 已安裝,再次執行 install 不會更新包版本, 執行 update 才會更新; 而如果本地 node_modules 為空時,執行 install/update 都會直接安裝更新包;

npm update 總是會把包更新到符合 package.json 中指定的 semver 的最新版本號——本例中符合的最新版本為

一旦給定 package.json, 無論後面執行 npm install 還是 update, package.json 中的 webpack 版本一直頑固地保持 一開始的巋然不動

這裡不合理的地方在於,如果最開始團隊中第一個人安裝了, 而新加入項目的成員, checkout 工程代碼後執行會安裝得到不太一樣的版本。雖然 semver 約定了小版本號應當保持向下兼容(相同大版本號下的小版本號)兼容,但萬一有不熟悉不遵循此約定的包發布者,發布了不兼容的包,此時就可能出現因依賴環境不同導致的 bug。

下面由 npm 5 帶著 package-lock.json 閃亮登場,執行 install/update 的效果是這樣的 (node 9.8.0, npm 5.7.1環境下試驗):

下表為表述簡單,省略了包名 webpack, install 簡寫 i, update 簡寫為 up

與 npm 3 相比,在安裝和更新依賴版本上主要的區別為:

無論何時執行 install, npm 都會優先按照 package-lock 中指定的版本來安裝 webpack; 避免了 npm 3 表中情形 b) 的狀況;

無論何時完成安裝/更新, package-lock 文件總會跟著 node_modules 更新 —— (因此可以視 package-lock 文件為 node_modules 的 JSON 表述)

已安裝 node_modules 後若執行 npm update,package.json 中的版本號也會隨之更改為

由此可見 npm 5.1 使得 package.json 和 package-lock.json 中所保存的版本號更加統一,解決了 npm 之前的各種問題。只要遵循好的實踐習慣,團隊成員可以很方便地維護一套應用代碼和 node_modules 依賴都一致的環境。

皆大歡喜。


總結起來,在 2018 年 (node 9.8.0, npm 5.7.1) 時代,我認為的依賴版本管理應當是:

使用 npm:版本, 保持文件默認開啟配置

初始化:第一作者初始化項目時使用安裝依賴包, 默認保存依賴 range 到 package.json中; 提交,,不要提交目錄

初始化:項目成員首次checkout/clone 項目代碼後,執行一次安裝依賴包

不要手動修改 package-lock.json

升級依賴包:

升級小版本: 本地執行升級到新的小版本

升級大版本: 本地執行升級到新的大版本

也可手動修改 package.json 中版本號為要升級的版本(大於現有版本號)並指定所需的 semver, 然後執行

本地驗證升級後新版本無問題後,提交新的,文件

降級依賴包:

正確:驗證無問題後,提交package.json 和 package-lock.json 文件

錯誤: 手動修改中的版本號為更低版本的 semver, 這樣修改並不會生效,因為再次執行依然會安裝中的鎖定版本

刪除依賴包:

Plan A:並提交和

Plan B: 把要卸載的包從 package.json 中 dependencies 欄位刪除, 然後執行並提交和

任何時候有人提交了 package.json, package-lock.json 更新後,團隊其他成員應在 svn update/git pull 拉取更新後執行腳本安裝更新後的依賴包

恭喜你終於可以跟&&這波操作說拜拜了(其實並不會)

npm scripts


npm scripts 是 npm 另一個很重要的特性。通過在 package.json 中 scripts 欄位定義一個腳本,例如:

我們就可以通過命令來執行這段腳本,像在 shell 中執行該命令一樣,看到終端輸出.

—— npm scripts 的基本使用就是這麼簡單,它提供了一個簡單的介面用來調用工程相關的腳本。關於更詳細的相關信息,可以參考阮一峰老師的文章 npm script 使用指南 (2016年10月).

簡要總結阮老師文章內容:

命令執行時,會把目錄添加到執行環境的變數中,因此如果某個命令行包未全局安裝,而只安裝在了當前項目的 node_modules 中,通過一樣可以調用該命令。

執行 npm 腳本時要傳入參數,需要在命令後加標明, 如可以將參數傳給命令

npm 提供了 pre 和 post 兩種鉤子機制,可以定義某個腳本前後的執行腳本

運行時變數:在的腳本執行環境內,可以通過環境變數的方式獲取許多運行時相關信息,以下都可以通過對象訪問獲得:

- 正在運行的腳本名稱

- 獲取當前包 package.json 中某個欄位的配置值:如獲取包名

- package.json 中嵌套欄位屬性:如可以獲取到 package.json 中的欄位的值,即 webpack 的版本號


上面所說的目錄,保存了依賴目錄中所安裝的可供調用的命令行包。

何謂命令行包?例如就屬於一個命令行包。如果我們在安裝 webpack 時添加參數,就可以在終端直接輸入進行調用。但如果不加參數,我們會在目錄里看到名為 webpack 的文件,如果在終端直接輸入命令,一樣可以執行。

這是因為在文件中定義了欄位為:

bin 欄位的配置格式為:, 即. npm 執行 install 時,會分析每個依賴包的 package.json 中的欄位,並將其包含的條目安裝到目錄中,文件名為。而如果是全局模式安裝,則會在 npm 全局安裝路徑的 bin 目錄下創建指向名為的軟鏈。因此,文件在通過命令行調用時,實際上就是在執行命令。

正如上一節所說,命令在執行時會把加入到中,使我們可直接調用所有提供了命令行調用介面的依賴包。所以這裡就引出了一個最佳實踐:

將項目依賴的命令行工具安裝到項目依賴文件夾中,然後通過 npm scripts 調用;而非全局安裝

舉例而言作為前端工程標配的構建工具,雖然我們都習慣了全局安裝並直接使用命令行調用,但不同的項目依賴的 webpack 版本可能不同,相應的配置文件也可能只兼容了特定版本的 webpack. 如果我們僅全局安裝了最新的 webpack 4.x 並使用 webpack 命令調用,在一個依賴 webpack 3.x 的工程中就會無法成功執行構建。

但如果這類工具總是本地安裝,我們要調用一個命令,要手動添加這個長長的前綴,未免也太麻煩了,我們 nodejs 開發者都很懶的。於是 npm 從5.2 開始自帶了一個新的工具.


npx 的使用很簡單,就是執行即可,這裡的默認就是目錄中安裝的可執行腳本名。例如上面本地安裝好的 webpack 包,我們可以直接使用執行即可。

除了這種最簡單的場景, npm cli 團隊開發者 Kat Marchán 還在這篇文章中介紹了其他幾種 npx 的神奇用法: Introducing npx: an npm package runner, 國內有位開發者 robin.law 將原文翻譯為中文 npx是什麼,為什麼需要npx?.

有興趣的可以戳鏈接了解,懶得點鏈接的,看總結:

場景a) 一鍵執行遠程 npm 源的二進位包

除了在 package 中執行 ./node_modules/.bin 中已安裝的命令, 還可以直接指定未安裝的二進位包名執行。例如我們在一個沒有 package.json 也沒有 node_modules 的目錄下,執行:

npx cowsay hello

npx 將會從 npm 源下載這個包(但並不安裝)並執行:

這種用途非常適合 1. 在本地簡單測試或調試 npm 源上這些二進位包的功能;2. 調用 create-react-app 或 yeoman 這類往往每個項目只需要使用一次的腳手架工具

PS: 此處有彩蛋,執行這條命令試試:

npx workin-hard場景b) 一鍵執行 GitHub Gist

還記得前面提到的 2.1 package定義 么,可以是包含了有效 package.json 的 git url.

剛好 GitHub Gist 也是 git 倉庫 的一種,集合 npx 就可以方便地將簡單的腳本共享給其他人,擁有該鏈接的人無需將腳本安裝到本地工作目錄即可執行。將 package.json 和 需執行的二進位腳本上傳至 gist, 在運行就可以方便地執行該 gist 定義的命令。

原文作者 Kat Marchán 提供了這個示例 gist, 執行:

npx https://gist.github.com/zkat/4bc19503fe9e9309e2bfaa2c58074d32

可得到一個來自 GitHubGist 的 hello world 問候。

場景c) 使用不同版本 node 執行命令

將 npx 與 Aria Stewart 創建的包 (https://www.npmjs.com/package/node) 結合,可以實現在一行命令中使用指定版本的 node 執行命令。

例如先後執行:

將分別輸出和.

往常這種工作是由這類 node 版本管理工具來做的,但這種方式免去 nvm 手動切換配置的步驟,更加簡潔簡單。

npm 配置


npm cli 提供了命令進行 npm 相關配置,通過可查看 npm 的所有配置,包括默認配置。npm 文檔頁為每個配置項提供了詳細的說明 https://docs.npmjs.com/misc/config .

修改配置的命令為, 我們使用相關的常見重要配置:

,: 指定 npm 使用的代理

指定 npm 下載安裝包時的源,默認為可以指定為私有 Registry 源

指定是否默認生成 package-lock 文件,建議保持默認 true

true/false 指定是否在 npm install 後保存包為 dependencies, npm 5 起默認為 true

刪除指定的配置項命令為.


除了使用 CLI 的命令顯示更改 npm 配置,還可以通過 npmrc 文件直接修改配置。

這樣的 npmrc 文件優先順序由高到低包括:

工程內配置文件:

用戶級配置文件:

全局配置文件:(即輸出的路徑)

npm內置配置文件:

因為項目級 .npmrc 文件的作用域只在本項目下,所以在非本目錄下,這些配置並不生效。對於使用筆記本工作的開發者,可以很好地隔離公司的工作項目、在家學習研究項目兩種不同的環境。

將這個功能與配置相結合,可以將特定配置的 .npmrc 跟 .gitignore, README 之類文件一起做到 npm init 腳手架中,進一步減少手動配置。


雖然一個項目的團隊都共享了相同的代碼,但每個人的開發機器可能安裝了不同的 node 版本,此外伺服器端的也可能與本地開發機不一致。

這又是一個可能帶來不一致性的因素 —— 但也不是很難解決,聲明式約束+腳本限制即可。

聲明:通過的屬性聲明應用運行所需的版本運行時要求。例如我們的項目中使用了,特性,查閱兼容性表格得知最低支持版本為 7.6.0,因此指定 engines 配置為:

強約束(可選):在 npm 中以上欄位內容僅作為建議欄位使用,若要在私有項目中添加強約束,需要自己寫腳本鉤子,讀取並解析 engines 欄位的 semver range 並與運行時環境做對比校驗並適當提醒。

小結 npm 最佳實踐

使用 npm-init 初始化新項目

統一項目配置: 需團隊共享的 npm config 配置項,固化到 .npmrc 文件中

統一運行環境,統一 package.json,統一 package-lock 文件

合理使用多樣化的源安裝依賴包:

使用 npm: >=5.2 版本

使用 npm scripts 與 npx (npm: >=5.2) 腳本管理應用相關腳本


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 雲加社區 的精彩文章:

基於深度學習和經典方法的文本分類
一個產品經理的社交6問

TAG:雲加社區 |