iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0
Modern Web

從Create到React—用來實作使用者介面的JavaScript函式庫系列 第 4

你所要知道的NPM基本知識關於package.json、semantic version及淺談update

  • 分享至 

  • xImage
  •  

觀看這篇文章將會提及以下內容

  • 安裝nodeJs
  • npm的本質
  • 初始化npm 建立package.json
  • 全域安裝
  • 區域安裝
  • 什麼是package.json
  • 相互依賴的node_module
  • 解除安裝
  • semantic version語義化版本
  • 更新package

安裝nodeJs

我們首先得從nodeJs官方網站下載

當下載node JS的時候安裝的時候,一直按下一步、下一步會預選默認安裝NPM

以下是下載後安裝時會出現的圖

圖中四點依據重要程度及簡單說明一下

  1. node js runtime Node Js執行(當然需要安裝)
  2. Npm 套件管理工具 (NPM相關套件時所需)
  3. 線上文件捷徑(不一定需要)
  4. add to path (添加到環境變數主要使用cli執行node命令)

當安裝完畢的時候想要知道是否有下載npm成功的話,可以在
terminal輸入 npm -v(查看npm版本號)
也可以輸入node -v (查看node版本號)
藉由輸入指令得知所安裝的版本號等同於有安裝成功了

npm的本質

包含兩個重要功能

  1. registry/repostitory 模組倉庫
  2. command line interface CLI介面

換句話說可以 用來載入第三方的module

初始化npm 建立package.json檔案

npm init 大致上會問幾個問題
如下

package name: (你的package名稱)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to 你的檔案路徑

基本上如果沒有要特別設定的話,就是一直按EnterEnterEnter,如果不小心Enter按太順也沒關係這些日後可以在package.json檔案修改。

如果覺得創建的時候每次都要按下這些冗長的問題很麻煩的話,npm init -y可以省略按Enter跳過步驟啟用預設值
最後就會產生一個package.json如下

{
  "name": "你的專案名字",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

以下就安裝部分分為全域安裝和區域安裝

全域安裝

全域安裝加入-g 表示全域安裝package,全域的package會安裝在系統中的一個位置(取決於你的設置)

為何需要全域安裝?

通常會是該module安裝cli指令集,讓其他專案也可以使用該指令集,例如輸入

使用方法加入-g可以安裝在這台電腦裏面
gulp為例(一個任務自動化管理工具)
npm install -g gulp-cli
安裝完gulp就可以在cli介面輸入gulp擁有的指令集進行編譯sass或者整合header和footer構成html或者css之類的事情,例如輸入gulp --tasks、gulp build之類的指令。

查看全域安裝的module

可以輸入npm -g list來看你所有安裝的全域環境的module

由於pakcage會形成一個dependency tree,透過限制深度,例如想要列出所安裝的pakckage不包含他們的依賴項時
就可以輸入npm list -g --depth 0

說明:列出全域安裝且深度是0的專案內容

區域安裝

通常安裝方式的指令是npm install "module名字"
也可以簡寫成npm i "module名字"
例如 npm i expressnpm i bootstrap

示範安裝bootstrap

以安裝bootstrp為例
輸入npm init 然後數個 Enter
然後
npm i bootstrap
最後安裝完成查看package.json會看到如第11行
dependencies增加了"bootstrap": "^5.0.2"
也就是這個project必須有bootstrap這個module才不會運行異常

{
  "name": "your-project-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bootstrap": "^5.0.2"
  }
}

觀察package.json

剛剛我們安裝了bootstrap,我們再安裝express輸入npm i express
這時候打開package.json會看到dependencies多了express,換句話說透過npm安裝模組會加入到package.json的檔案中,成為該專案的依賴項

{
  "name": "your-project-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "bootstrap": "^5.0.2",
    "express": "^4.17.1"
  
}

什麼是package.json

上一個部分觀察到package.json會加入專案的依賴項,每個專案通常都會有一個package.json
package.json通常包含許多資訊例如
專案名稱、版本、作者、 github repo

從其他github下載下來的檔案可以藉由package.json來了解所需的module然後透過npm install自動去npm的庫安裝所需清單

這邊可以歸類以下點

  • 做為一個描述檔案及專案所需依賴的package
  • 使用語義化版本(semantic versioning)規則指定專案依賴pakcage的版本
  • 易於與開發者分享、重複使用

-save該輸入嗎?什麼是-dev

或許你會看到有些網路上的文章所輸入的是npm install --save '套件名稱',有些卻沒有--save,這是因為
在npm5.0.0以前在安裝套件的時候必須打--save才能安裝
例如npm install --save boostrap

在npm 5版之後可以省略--save因此只要打npm install boostrap

如果這個套件只有在測試的時候,而非實際上架部署才會需要用到的套件的化,可以打
npm install sass --save-dev

另外--save-dev也有簡寫,可以打-D來替代-dev如下
npm i sass -D

相互依賴的node_module

如果你已經安裝了某個套件例如express,嘗試著打開node_modules這個資料夾
可以看到產生的東西這麼多內容如下

express這個modules也仰賴其他modules,因此打開裡面的package-lock.json,可以看到在初次安裝的時候鎖定的版本號,並且也能從中得知express仰賴其他的modules

 "node_modules/body-parser": {
      "version": "1.19.0",
      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
      "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
      "dependencies": {
        "bytes": "3.1.0",
        "content-type": "~1.0.4",
        "debug": "2.6.9",
        "depd": "~1.1.2",
        "http-errors": "1.7.2",
        "iconv-lite": "0.4.24",
        "on-finished": "~2.3.0",
        "qs": "6.7.0",
        "raw-body": "2.4.0",
        "type-is": "~1.6.17"
      },

所以有個迷因圖node_module比黑洞的重力場還要重
如下圖

圖片來源 Heaviest Objects In The Universe-reddit

npx是什麼?

在npm5.2版本號前如果想要執行某些指令需要進行全域安裝,透過npx的方式可以無需安裝任何東西就能執行某些命令。

以framework為例

我們想要創建一個新的應用程式時需要執行vue的指令,可以透過npx create-react-app my-react-app,由於create-react-app這個指令只會在創建應用程式時候使用,透過npx可以執行完創建指令後就刪除。換句話說,不想要全局安裝以及想要一次性執行完便刪除的module,可以考慮使用npx。

更多也可以參考官方The Npx Node.Js Package Runner

解除安裝

前面提到的都是安裝
想當然而也可以解除安裝一些不再需要用到的套件

輸入npm uninstall "module名字"

例如輸入npm uninstall expressnpm uninstall bootstrap

打開node_modules資料夾就只會剩下大致如下

├─node_modules
│  │  .package-lock.json
│  │
│  └─.bin

semantic version語義化版本

你可能覺得奇怪
為什麼版本號不是十進位的

圖片來源Setting Up Automated Semantic Versioning For Your NodeJS Project

因為版本號具有語意
例如2.3.12第一個主要版本是2,代表如果版本3是不會向下相容,而且具有大規模的變化,因此也會造成以前撰寫的code出現問題。

第二個版本號3是有新增新的特色並且具備向下相容
理論上(ideally)是不會毀壞以前的code

第三個版本號只是修改一些小bug而已
是不會毀壞以前的code

例如原先是1.2.15在更改大版本號的時候就會變成2.0.0

更改次要版本號的時候例如1.2.15下個版本就會變成1.3.0

更多詳細也可以參考官方文檔NPM-About semantic versioning

package-lock.json版本號

其實用一句話來概括很簡單,就是鎖定安裝時的包的版本號,並且需要上傳到git,以保證其他人在npm install時大家的依賴能保證一致

一般的package.json只能鎖定大版本號,由於開發者撰寫版本號的時候也可能不遵守具有語意的版本號編寫方式,在不同時間下載npm也可能造成版本不同,所以就可能造成程式出問題。

package.json的內容更新模式

也許你會看到^4.1.0在package.json

^符號表意思是如果你從其他github下載下來後 再npm install就會自動更新到最新的次要版本 例如網路上有4.2.1版本的時候就會選擇安裝這個版本

~表示會安裝到最新的patch版本號
例如4.19.5 網路上有4.19.10就會安裝到4.19.10這個版本 不會影響minor 版本

查看當前專案安裝的module和版本號指令

你可以輸入npm list來列出你所安裝的所有module和版本號

列出該module所有版本號指令

輸入npm view "module" versios列出所有版本名字

更新pakcage

當你輸入npm update自動把所有的依賴安裝到最新的版本,但只有更新到最新相容的版本號,所以如果5.0.0被發布的時候 他並不會被更新到5.0.0

但也會造成可能有些套件並不想更新的套件也會一併更新

指定某個套件安裝最新版本

如果想要手動安裝最新的主要版本則輸入
npm install chalk@latest就是npm安裝最後的版本

指定安裝某個主要版本

指定安裝npm install chalk@2
就會安裝最新的主要版本是2的module 也就是2.X.X

列出尚未更新到最新版本的依賴

使用 npm outdated 可以幫助我們列出有哪些還沒有升級到最新版本的依賴

選擇性的更新你所要的套件

另外為了方便選擇更新我們要更新的套件可以安裝以下套件

npm install -g npm-check

安裝完畢後可以輸入npm-check還有npm-check -u 就可以用打勾的方式更新

更多可以參照官方npm-check介紹

module與仰賴其他module密不可分

由於許多module也依賴其他module,因此如果遇到更新的時候很可能造成整個module壞掉更新的時候需要三思阿

本日基本介紹npm用法,以下參考資料也能稍微觀看一下能加固對npm的知識。

資料參考來源

上一篇
為什麼需要模組化?—ESModule模組介紹、React整理code技法與基本技巧
下一篇
從編譯Sass實作來理解webpack前端自動化打包工具
系列文
從Create到React—用來實作使用者介面的JavaScript函式庫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndrewYEE
iT邦新手 3 級 ‧ 2023-02-10 19:20:11

謝謝

DannyChen iT邦研究生 5 級 ‧ 2023-02-10 21:13:53 檢舉

不客氣~/images/emoticon/emoticon37.gif

我要留言

立即登入留言