[npm]該使用npm install? 還是npm ci?
===
###### tags: `Node.js` `工作筆記` `前端` `npm`
## 這是一個在工作上遇到的故事:
1. A同仁在push master分支時出package-lock.json現大量的conflict,因為他有安裝一些新的npm套件,就選擇以自己的版本取代。
2. 其他同仁pull時發現conflict也不疑有他,把master的版本取代本機版本
3. 突然有一天C同仁發現某個正在使用的npm套件功能故障了,原因是那個套件被更新到最新版(新版本有issues)
4. 但很多同仁說自己的npm套件功能,在本機run完全沒問題啊! 怎麼在C同仁的電腦會故障?
5. 攤開大家的`node_mudules`資料夾,發現很多版本不相同的地方
6. 詢問了到底是誰改了那個npm套件的版本? 結果所有人都說自己沒改...
NPM簡介
---
NPM 是 Node Package Manager 的縮寫,是 Node.js 預設的 node 套件管理平台,去年納入GitHub麾下。
當撰寫網頁應用程式時,會使用到其他撰寫好的套件或模組,當我們使用的套件或模組越來越多時,套件的版本或相容管理上就會大大增加複雜度,這時候就需要使用npm來進行協助。(功能類似後端的Maven)
## package.json
透過 npm 指令使用者可以更方便進行套件的管理動作 (安裝、升級或刪除),並將專案需使用到的套件寫入設定檔`package.json`,npm 會一併安裝管理。 (功能類似Maven的`pom.xml`)

package.json的版本的寫法,以express這個套件名來說:
:::success
"express": "2.5.1" => 只能使用2.5.1的版本(推薦)
"express": "latest" => 使用最新版本,每次更新都會檢查是否有新版本 (十分不推薦)
"express": ">= 2.5.1" => 所有比2.5.1還新的版本
"express": “~2.5.1" => 所有比2.5.1還新的2.5.x的版本,但不會到2.6.0
"express": “^2.5.1" => 所有比2.5.1還新的2.x.x的版本,但不會到3.0.0
:::
## package-lock.json
當你寫好了專案所需的`package.json`後執行`npm install`指令,將需要的套件下載進`node_mudules`內,這時`node_mudules`內==當下的版本號==就會記錄在`package-lock.json`

## npm install 🆚 npm ci
:::info

:::
:::success

:::
這邊可以看到使用`npm install`後,有可能會rewrite `package.json` 和 `package-lock.json`,而`npm ci`並不會。
原因是`npm ci` (also known as Clean Install) ,這個指令主要用於自動化部屬(CI/CD)或者是測試環境,他只會針對`package-lock.json`內的套件版本資訊去還原下載至`node_mudules`
而`npm install`在每次下載時會去刷`package.json`,如果不當初沒有指定版本的話,就會去檢查有無新的版本,有的話就會==下載新的版本,並更新該版本進`package-lock.json`==。
這邊就可以發現我們小故事的兇手就是`npm install`了,因為當初專案剛建立時,部分套件的版本並未指定。而同仁在使用`npm install`時修改了`package-lock.json`並將檔案上傳到版控的git上。
於是造成其他同仁pull下來`package.json`和`package-lock.json`,之後使用npm install或是npm ci去下載進`node_mudules`會變成新的版本。
但pull下來後沒有執行`npm install`或是`npm ci`的話,你的`node_mudules`還會是最一開始的版本。
## 結論
* 建議在撰寫`package.json`時指定好固定版本。
* 在專案code裡面若有看到`package-lock.json`這個檔案的話,都建議使用`npm ci`。
* 上了版控的專案,除非你是專案建置的第一人,或者你要新增一個原本`package.json`內沒有的套件,才會使用到`npm install`。
#### 參考來源:
[What is the difference between "npm install" and "npm ci"?](https://stackoverflow.com/questions/52499617/what-is-the-difference-between-npm-install-and-npm-ci)
[npm ci vs. npm install — Which Should You Use in Your Node.js Projects?](https://betterprogramming.pub/npm-ci-vs-npm-install-which-should-you-use-in-your-node-js-projects-51e07cb71e26)