2019年1月15日 星期二

Node.js 學習筆記 : 套件管理工具 npm

隨著 Node 安裝的 npm 是 Node 的套件管理工具 (Node Package Management), 功能類似 Python 的 pip 或 Ruby 的 gem, 都是用來管理與分享模組或套件的中介軟體, 主要是用來線上安裝第三方模組, 只要指定套件名稱, npm 會從網路下載欲安裝的套件以及其相依之模組進行安裝, 預設之模組下載來源為 :

# https://www.npmjs.org

經過 npm 安裝好的套件便可像內建的核心模組那樣用 Node 的全域指令 require 引用至應用程式中使用.

Node.js 雖然主要是伺服端的 Javascript 框架, 但另外一個身分是跳脫瀏覽器藩籬而獨立的 Javascript 執行時期環境, 亦即只要安裝了 Node.js 便能執行任何 Javascript 程式檔案. 這使得許多 Javascript 應用例如前端網頁框架的 Vue 等也利用 Node.js 的 npm 套件管理功能來配置其檔案與目錄.

Node 的模組系統遵循 Common JS 模組系統架構, 此架構規範 Node 模組的製作方式, 開發者需照此規範建立模組, 這樣才能確保模組之間互相運作順暢 (Interoperable). npm 官網與說明文件網址如下 :

# http://npmjs.org
https://docs.npmjs.com/

目前 npm 已有超過 88 萬個 Node 第三方套件可供下載安裝, 而且持續不斷快速增加中 :




npm 必須在命令列執行, 開啟命令提示字元視窗, 輸入 npm -v 會顯示目前已安裝的 npm 版本, 例如 :

Microsoft Windows [版本 10.0.17134.556]
(c) 2018 Microsoft Corporation. 著作權所有,並保留一切權利。

C:\Users\User>npm -v 
6.4.1 

若要更新 npm 版本至最新, 可輸入 npm update -g npm, 例如 :

C:\Users\User>npm update npm -g 

若輸入 npm update -g 則是更新所有已安裝套件與其相依模組至最新, 這可能會耗費較久時間.

npm 指令格式為 npm <command> 常用的指令如下 :

 npm 常用指令 說明
 npm install pkg 安裝套件 pkg
 npm uninstall pkg 刪除已安裝套件 pkg
 npm list 顯示全部已安裝套件
 npm view pkg 查詢套件資訊如版本, 相依模組等 (JSON)
 npm search pkg 搜尋套件 pkg
 npm cache 顯示或清除 npm 上的快取
 npm publish pkg 上傳套件 pkg 至 npmjs.org
 npm unpublish pkg 把已上傳至 npmjs.org 之套件 pkg 移除
 npm home pkg 開啟套件 pkg 首頁
 npm repo pkg 開啟套件 pkg 寄存庫 (repository)
 npm update pkg 更新套件 pkg 與其相依模組至最新版本


例如輸入 npm help 會顯示 npm 之用法說明, 輸入 npm list 會顯示目前已安裝之套件 :

Microsoft Windows [版本 10.0.17134.556]
(c) 2018 Microsoft Corporation. 著作權所有,並保留一切權利。

C:\Users\User>npm help 

Usage: npm <command> 

where <command> is one of:
    access, adduser, audit, bin, bugs, c, cache, ci, cit,
    completion, config, create, ddp, dedupe, deprecate,
    dist-tag, docs, doctor, edit, explore, get, help,
    help-search, hook, i, init, install, install-test, it, link,
    list, ln, login, logout, ls, outdated, owner, pack, ping,
    prefix, profile, prune, publish, rb, rebuild, repo, restart,
    root, run, run-script, s, se, search, set, shrinkwrap, star,
    stars, start, stop, t, team, test, token, tst, un,
    uninstall, unpublish, unstar, up, update, v, version, view,
    whoami

npm <command> -h  quick help on <command>
npm -l            display full usage info
npm help <term>   search for help on <term>
npm help npm      involved overview

Specify configs in the ini-formatted file:
    C:\Users\User\.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config

npm@6.4.1 C:\nodejs\node_modules\npm

C:\Users\User>npm list 
C:\Users\User
`-- (empty)     

因還沒有安裝任何第三方套件故顯示 empty.

輸入 npm view pkg 會查詢指定套件之相依模組與最新版本等資訊, 例如查詢 Express 套件 :

C:\Users\User>npm view express

express@4.16.4 | MIT | deps: 30 | versions: 261
Fast, unopinionated, minimalist web framework
http://expressjs.com/

keywords: express, framework, sinatra, web, rest, restful, router, app, api

dist
.tarball: https://registry.npmjs.org/express/-/express-4.16.4.tgz
.shasum: fddef61926109e24c515ea97fd2f1bdbf62df12e
.integrity: sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==
.unpackedSize: 206.1 kB

dependencies:
accepts: ~1.3.5            depd: ~1.1.2               on-finished: ~2.3.0
array-flatten: 1.1.1       encodeurl: ~1.0.2          parseurl: ~1.3.2
body-parser: 1.18.3        escape-html: ~1.0.3        path-to-regexp: 0.1.7
content-disposition: 0.5.2 etag: ~1.8.1               proxy-addr: ~2.0.4
content-type: ~1.0.4       finalhandler: 1.1.1        qs: 6.5.2
cookie-signature: 1.0.6    fresh: 0.5.2               range-parser: ~1.2.0
cookie: 0.3.1              merge-descriptors: 1.0.1   safe-buffer: 5.1.2
debug: 2.6.9               methods: ~1.1.2            send: 0.16.2
(...and 6 more.)

maintainers:
- dougwilson <doug@somethingdoug.com>
- hacksparrow <captain@hacksparrow.com>
- jasnell <jasnell@gmail.com>
- mikeal <mikeal.rogers@gmail.com>

dist-tags:
latest: 4.16.4       next: 5.0.0-alpha.7

published 3 months ago by dougwilson <doug@somethingdoug.com>

可見 Express 目前最新版本為 4.16.4.

用 npm 安裝第三方套件時, 安裝位置有下列兩種 :
  1. 區域安裝 :
    npm install 預設 (不加 -g 參數) 會將套件安裝在目前資料夾的 node_modules 下, 因此不同的專案要用到相同套件時都要重新安裝一次, 但透過多重安裝卻可解決版本衝突問題, 因為在用 require 引入同一模組時, 只會從該專案目錄下的 node_modules 下尋找該模組, 因此各專案目錄下的相同套件 (版本可能不同) 彼此是隔離互不影響的. 不過, 區域安裝的套件只是被安裝到 node_modules 下而已, 其下的 bin 子目錄並不會註冊到 PATH 環境變數中, 因此無法在命令列直接執行此模組之執行檔.  
  2. 全域安裝 :
    npm install 指令若加上 -g 參數會將安裝在 Node 的安裝目錄下 (Linux 通常是在 /usr/local/lib/node_modules), 同時會將其下的 bin 子目錄註冊到 PATH 環境變數中, 因此可在命令列直接執行此模組之執行檔. 在 Linux 系統中, 全域安裝除了將模組安裝到 /usr/local/lib/node_modules 下之外, package.json 檔案中 bin 欄位所列之執行檔也會被連結到 /usr/local/bin, 此為 PATH 環境變數之預設路徑, 因此可在命令列下執行.
    不過在 Linux 系統下, 全域安裝的模組不能直接在 js 檔中用 require 引入模組, 因為 require 不會搜索 /usr/local/lib/node_modules 目錄, 但可用 npm link 在專案目錄與全域模組之間建立符號連結來解決此問題 (npm link 不支援 Windows). 
以安裝架站框架 Express 為例, 區域安裝指令如下 :

npm install express

npm install 指令會連線 npm 套件資料庫, 下載指定套件與其所有相依的模組, 全部安裝於目前目錄的子目錄 node_modules 下 (自動建立).

安裝完畢就可以在程式中以 require 指令引用新安裝的套件, 這時 Node 會到 node_modules 子目錄下找尋已安裝的模組來用 :

var express=require('express');

npm 預設是區域安裝, 亦即只有在目前 App 目錄下的程式可引用所安裝的第三方套件, 別的 App 目錄如果也要用到此套件必須在該目錄下再次安裝. 此外, 區域安裝不會將 node_modules 底下的 bin 子目錄註冊在 PATH 環境變數中. 區域安裝的模組是 require 指令最優先搜尋的位置, 亦即, 當 Node 執行 require('module_name') 時會先到 node_modules 子目錄下搜尋 'module_name' 模組並載入到 cache 記憶體中.

如果要讓任何目錄下的程式都能引用所安裝的模組, 必須用全域安裝, 因它會註冊 PATH 環境變數, 方法是在 npm install 指令後面加 -g 選項 (Linux 要加 sudo), 例如 :

npm install express -g

Node 的 npm 與 Python 的 pip, Ruby 的 gem 最大不同就是有分區域與全域安裝 (預設是區域安裝), 而 pip 與 gem 都是全域安裝, 優點是安裝一次, 全部應用程式都可使用, 但缺點是會有版本衝突問題. 區域安裝優點是各 App 不用擔心版本衝突問題, 但缺點則是同一個模組可能會在不同專案目錄安裝很多次.

npm install 預設安裝最新版模組, 但也可以指定版本, 格式是在套件名稱後面以 @ 指定版本號, 例如指定安裝 Express v4.4.3 版 :

npm install express@4.4.3  

此外 npm install 也可以從本機檔案系統中已從 GitHub 下載的套件資料夾安裝, 但要先安裝 git, 用 git clone 指令先下載套件, 例如下載 Express :

$ git clone https://github.com/visionmedia/express.git

然後用 npm install 安裝 :

$ npm install ./express 

沒有留言 :