Node.js 讓 JavaScript 編寫伺服器端應用程式成為可能。它建立在 JavaScript V8(C++ 編寫的) 執行時之上,所以它很快。最初,它旨在為應用程式提供伺服器環境,但是開發人員開始利用它來建立工具,幫助他們本地的任務自動化。此後,一個全新基於 Node 工具(如 Grunt 和 Gulp)的生態系統,使得前端開發改頭換面。
要使用 Node.js 中的這些工具(或包),我們需要一種有效的方式來安裝和管理它們。這就要用到node 包管理器: npm 了。它能夠安裝你想要的包,而且提供一個強大介面來使用它們。在使用 npm 之前,首先得在系統上安裝 Node.js。
安裝 Node.js
先去 Node.js 的下載頁面,然後選擇你需要的版本。有 Windows 和 Mac 版的安裝程式可以用,還有預編譯的 Linux 二進位制檔案和原始碼。對於 Linux ,也可以用包管理器來安裝 Node,下面將詳細介紹。
這篇教程中使用的是 v.5.7.0 穩定版。
先看看 node 被安裝到哪了,然後確認下版本。
1 2 3 4 |
$ which node /usr/local/bin/node $ node --version v5.7.0 |
驗證下安裝是否成功,試試 Node REPL 。
1 2 3 4 5 6 7 8 9 10 11 |
$ node > console.log('Node is running'); Node is running > .help .break Sometimes you get stuck, this gets you out .clear Alias for .break .exit Exit the repl .help Show repl options .load Load JS from a file into the REPL session .save Save all evaluated commands in this REPL session to a file > .exit |
安裝的 Node.js 工作了,那麼把注意力集中到 npm 上吧,安裝 Node.js 過程中也安裝了 npm 。
1 2 3 4 |
$ which npm /usr/local/bin/npm $ npm --version 3.6.0 |
Node 包模組
npm 有兩種模式安裝包,local(本地) 和 global(全球) 。在 local 模式下,它會安裝 node_modules 資料夾(在工作目錄的父目錄)中的包。這個位置是屬於當前使用者的。Global 包安裝在 root 使用者下 {prefix}/lib/node_modules/ ({prefix} 通常是 /usr/ 或者 /usr/local)。這就意味需要使用 sudo 命令來安裝 global 包,否則當解析第三方包依賴時,出於安全考慮可能會出現許可權錯誤。 讓我們來修改下:
看看 npm config 輸出了些啥。
1 2 3 4 5 6 7 8 |
$ npm config list ; cli configs user-agent = "npm/3.6.0 node/v5.7.0 linux x64" ; node bin location = /usr/local/bin/node ; cwd = /home/sitepoint ; HOME = /home/sitepoint ; 'npm config ls -l' to show all defaults. |
輸出了一些安裝資訊。現在獲取當前 global 位置是很重要的。
1 2 |
$ npm config get prefix /usr/local |
這是我們想要改變的字首,那樣就能把 global 包安裝到我們的 home 目錄中。在你的 home 資料夾中建立一個新的目錄。
1 2 |
$ cd && mkdir .node_modules_global $ npm config set prefix=$HOME/.node_modules_global |
簡單的修改下配置,就把 Node global 包的安裝位置改變了。這個操作也會在我們的 home 目錄中生成一個 .npmrc 檔案。
1 2 3 4 |
$ npm config get prefix /home/sitepoint/.node_modules_global $ cat .npmrc prefix=/home/sitepoint/.node_modules_global |
npm 安裝位置仍然在 root 使用者的目錄中。但因為改變了 global 包的位置,所以可以利用這一點。我們需要重新安裝 npm,但這次安裝在新使用者自備的位置。這次也是安裝最新版本的 npm。
1 2 3 4 |
$ npm install npm --global /home/sitepoint/.node_modules_global/bin/npm -> /home/sitepoint/.node_modules_global/lib/node_modules/npm/bin/npm-cli.js /home/sitepoint/.node_modules_global/lib └── npm@3.7.5 |
最後,需要將 .node_modules_global/bin 新增到環境變數 $PATH 中,這樣就可以在命令列中執行 global 包命令。將下面這行命令追加到 .profile 或 .bash_profile 中,然後重啟終端。
1 |
export PATH="$HOME/.node_modules_global/bin:$PATH" |
現在就會先發現 .node_modules_global/bin,然後使用正確版本的 npm。
1 2 3 4 |
$ which npm /home/sitepoint/.node_modules_global/bin/npm $ npm --version 3.7.5 |
Global 模式下安裝包
目前只安裝了一個 global 包,那就是 npm 本身。所以讓我們來試試其他的,安裝 UglifyJS(一個 JavaScript 壓縮工具 )。我們將使用 –global 標識,可以簡寫成 -g。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ npm install uglify-js --global /home/sitepoint/.node_modules_global/lib └─┬ uglify-js@2.6.2 ├── async@0.2.10 ├── source-map@0.5.3 ├── uglify-to-browserify@1.0.2 └─┬ yargs@3.10.0 ├── camelcase@1.2.1 ├─┬ cliui@2.1.0 │ ├─┬ center-align@0.1.3 │ │ ├─┬ align-text@0.1.4 │ │ │ ├─┬ kind-of@3.0.2 │ │ │ │ └── is-buffer@1.1.2 │ │ │ ├── longest@1.0.1 │ │ │ └── repeat-string@1.5.4 │ │ └── lazy-cache@1.0.3 │ ├── right-align@0.1.3 │ └── wordwrap@0.0.2 ├─┬ decamelize@1.1.2 │ └── escape-string-regexp@1.0.5 └── window-size@0.1.0 |
正如從輸出中所看到的,額外的一些包也被安裝了,這些都是 uglify.js 所依賴的其他包。
列出所有 global 包
可以用 npm list 命令列出所有我們安裝的 global 包。
1 2 3 4 5 6 7 8 9 10 11 |
$ npm list --global ├─┬ npm@3.7.5 │ ├── abbrev@1.0.7 │ ├── ansi-regex@2.0.0 │ ├── ansicolors@0.3.2 │ ├── ansistyles@0.1.3 .................... └─┬ uglify-js@2.6.2 ├── async@0.2.10 ├── source-map@0.5.3 ├── uglify-to-browserify@1.0.2 |
不過輸出太冗長了。可以使用 –depth=0 引數來控制輸出。
1 2 3 |
$ npm list -g --depth=0 ├── npm@3.7.5 └── uglify-js@2.6.2 |
這就好多了,只輸出安裝的包和它們的版本號。
可以在終端中使用 uglifyjs 解析 JavaScript 檔案。例如使用下面的命令可以將 example.js 轉換成 example.min.js :
1 |
$ uglifyjs example.js -o example.min.js |
local 模式安裝包
local 模式安裝包去掉 –global 引數就行了。包將被安裝在父級工作目錄中一個 node_modules 資料夾裡。在 home 目錄中建立一個資料夾:
1 2 3 4 5 6 7 8 |
$ mkdir ~/project && cd ~/project $ npm install underscore /home/sitepoint/project └── underscore@1.8.3 $ ls node_modules $ ls node_modules underscore |
列出所有 local 包
和 global 包一樣,使用 npm list 命令就能列出所有 local 包。
1 2 3 |
$ npm list /home/sitepoint/project └── underscore@1.8.3 |
正如你所見,我們可以把 local 包安裝在任何我們想安裝的位置。這就意味著可以建立另外一個目錄然後安裝一個不同版本的 underscore。
解除安裝 local 包
npm 是一個包管理器,所以它肯定也可以解除安裝一個包。讓我們假設當前版本的 underscore 包存在相容問題。移除當前的包然後安裝一個老版本的,像這樣:
1 2 3 4 5 |
$ npm uninstall underscore - underscore@1.8.3 node_modules/underscore $ npm list /home/sitepoint/project └── (empty) |
安裝一個指定版本的包
現在可以安裝我們想要的版本的 underscore 包。@ 後面追加版本號就可以了。
1 2 3 4 5 6 |
$ npm install underscore@1.8.2 /home/sitepoint/project └── underscore@1.8.2 $ npm list /home/sitepoint/project └── underscore@1.8.2 |
更新包
最新版本的 underscore 修復了一些之前的 bug ,然後我們想要更新包到最新版本。
1 2 3 4 5 |
$ npm update underscore underscore@1.8.3 node_modules/underscore $ npm list /home/sitepoint/project └── underscore@1.8.3 |
注意:對於這項操作,underscore 已經在 package.json 中已經被當成依賴列出來了(看看如何管理依賴)。
搜尋包
在本教程中多次使用 mkdir 命令。是否有一個 node 包 來做這件事情呢?
1 2 |
$ npm search mkdir npm WARN Building the local index for the first time, please be patient |
有個 mkdirp。安裝它。
1 2 3 4 |
$ npm install mkdirp /home/sitepoint/project └─┬ mkdirp@0.5.1 └── minimist@0.0.8 |
現在建立一個 mkdir.js 檔案。
1 2 3 4 5 |
var mkdirp = require('mkdirp'); mkdirp('foo', function (err) { if (err) console.error(err) else console.log('Directory created!') }); |
然後在終端中執行它:
1 2 |
$ node. mkdir.js Directory created! |
管理快取
當 npm 安裝一個包的時候它會維護一個副本,下次你想再次安裝那個包的時候,就不用再去訪問網路重新下載了。那些副本會在 home 目錄 .npm 資料夾中快取起來。
1 2 |
$ ls ~/.npm _locks minimist mkdirp registry.npmjs.org underscore |
隨著時間推移,這個目錄裡會有很多老的包,十分的混亂,所以時常清理下是十分有必要的。
1 |
$ npm cache clean |
管理依賴
目前在我們的專案目錄中只安裝了兩個包,不過包的數量會增長的非常快。手動安裝依賴是非常不明智的,所以可以在專案目錄中用 package.json 檔案來管理它們。通過 nmp init 命令可以建立。
1 2 3 4 5 6 7 8 9 10 11 12 |
$ npm init This utility will walk you through creating a package.json file. Press ^C at any time to quit. name: (project) demo version: (1.0.0) description: Demo of package.json entry point: (index.js) test command: git repository: keywords: author: Sitepoint license: (ISC) |
這會在專案根目錄中建立下面的檔案
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "name": "demo", "version": "1.0.0", "description": "Demo package.json", "main": "main.js", "dependencies": { "mkdirp": "^0.5.1", "underscore": "^1.8.3" }, "devDependencies": {}, "scripts": { "test": "echo "Error: no test specified" && exit 1" }, "author": "Sitepoint", "license": "ISC" } |
如果你想快速生成一個 package.json 檔案的話,使用下面的命令:
1 |
$ npm init --yes |
會快速建立一個 package.json 檔案,你的目錄名會被作為 name 屬性。
還可以新增引數 private: true 防止私有庫不小心被髮布,還能消除執行 npm 安裝時的各種警告。讓我們建立一個新的目錄,使用 package.json 檔案來安裝依賴。
1 2 3 4 5 6 7 8 |
$ mkdir ~/demo && cd ~/demo $ cp ~/project/package.json ~/demo $ npm install $ npm list demo@1.0.0 /home/sitepoint/demo ├─┬ mkdirp@0.5.1 │ └── minimist@0.0.8 └── underscore@1.8.3 |
看看基於 package.json 檔案在另外一個目錄中安裝包是多麼的簡單。但是當安裝新包的時候如何讓它保持最新呢?我們可以使用 –save 標識。
1 2 3 4 5 6 |
$ npm install request --save $ npm list --depth=0 demo@1.0.0 /home/sitepoint/demo ├── mkdirp@0.5.1 ├── request@2.53.0 └── underscore@1.8.3 |
然後 package.json 也就被更新了。
1 2 3 4 5 |
"dependencies": { "mkdirp": "^0.5.1", "request": "^2.53.0", "underscore": "^1.8.3" } |
版本管理
有些工具可以幫你在同一臺機器上管理不同版本的 Node.js。有個叫 n 的工具。還有個是 nvm(Node Version Manager)。如果你對這些有興趣的話,不妨看看我們另外一篇教程: 使用 nvm 安裝多版本 Node.js。
總結
在這篇教程中,講解了使用 npm 工作的基本知識。展示瞭如何從專案下載頁面安裝 Node.js,如何修改 global 包的位置(避免使用 sudo 命令),還有如何在 local 、 global 模式下安裝包。以及刪除、更新、安裝指定版本的包,最後還有管理專案依賴。
你會在專案中使用 npm 嗎?在 npm 倉庫有數以千計的包,隨著 jQuery 外掛也能快速在 npm 倉庫釋出,包的數量肯定會保持增長。哪些包對你來講不可或缺?