1. 程式人生 > >npm模組管理器入門(轉載)

npm模組管理器入門(轉載)

npm模組管理器入門(轉)

作者原文地址:https://www.cnblogs.com/slly/p/7927760.html

npm模組管理器入門

什麼是 NPM
npm 是 Node 官方提供的包管理工具,他已經成了 Node 包的標準釋出平臺,用於 Node 包的釋出、傳播、依賴控制。
npm 提供了命令列工具,使你可以方便地下載、安裝、升級、刪除包,也可以讓你作為開發者釋出並維護包。

為什麼要使用 NPM
npm 是隨同 Node 一起安裝的包管理工具,能解決 Node 程式碼部署上的很多問題,常見的場景有以下幾種:

允許使用者從 npm 伺服器下載別人編寫的第三方包到本地使用。
允許使用者從 npm 伺服器下載並安裝別人編寫的命令列程式到本地使用。
允許使用者將自己編寫的包或命令列程式上傳到 npm 伺服器供別人使用。
npm 的背後,是基於 CouchDB 的一個數據庫,詳細記錄了每個包的資訊,包括作者、版本、依賴、授權資訊等。它的一個很重要的作用就是:將開發者從繁瑣的包管理工作(版本、依賴等)中解放出來,更加專注於功能的開發。

如何使用 NPM
安裝

npm 不需要單獨安裝。在安裝 Node 的時候,會連帶一起安裝 npm 。但是,Node 附帶的 npm 可能不是最新版本,最後用下面的命令,更新到最新版本。

1
$ sudo npm install [email protected] -g
如果是 Window 系統使用以下命令即可:

1
npm install npm -g
也就是使用 npm 安裝自己。之所以可以這樣,是因為 npm 本身與 Node 的其他模組沒有區別。

然後,執行下面的命令,檢視各種資訊。

1
2
3
4
5
6
7
8
9
10
11

檢視 npm 命令列表

$ npm help

檢視各個命令的簡單用法

$ npm -l

檢視 npm 的版本

$ npm -v

檢視 npm 的配置

$ npm config list -l
使用

npm init

npm init 用來初始化生成一個新的 package.json 檔案。它會向用戶提問一系列問題,如果你覺得不用修改預設配置,一路回車就可以了。
如果使用了 -f(代表force)、-y(代表yes),則跳過提問階段,直接生成一個新的 package.json 檔案。

1
$ npm init -y
npm set

npm set 用來設定環境變數

1
2
3
4
$ npm set init-author-name ‘Your name’
$ npm set init-author-email ‘Your email’
$ npm set init-author-url ‘

http://yourdomain.com
$ npm set init-license ‘MIT’
上面命令等於為 npm init 設定了預設值,以後執行 npm init 的時候,package.json的作者姓名、郵件、主頁、許可證欄位就會自動寫入預設的值。這些資訊會存放在使用者主目錄的 ~/.npmrc檔案,使得使用者不用每個專案都輸入。如果某個專案有不同的設定,可以針對該專案執行 npm config。

npm info

npm info 命令可以檢視每個模組的具體資訊。比如,檢視 underscore 模組的資訊。

1
$ npm info underscore
上面命令返回一個 JavaScript 物件,包含了 underscore 模組的詳細資訊。這個物件的每個成員,都可以直接從 info 命令查詢。

1
2
3
4
5
$ npm info underscore description

$ npm info underscore homepage

$ npm info underscore version
npm search

npm search 命令用於搜尋 npm 倉庫,它後面可以跟字串,也可以跟正則表示式。

1
$ npm search <搜尋詞>
npm list

npm list 命令以樹形結構列出當前專案安裝的所有模組,以及它們依賴的模組。

1
2
3
4
5
6
7
$ npm list

加上 global 引數,會列出全域性安裝的模組

$ npm list -global

npm list 命令也可以列出單個模組

$ npm list underscore
npm install

使用 npm 安裝包的命令格式為:npm [install/i] [package_name]

本地模式和全域性模式

npm 在預設情況下會從 NPM 搜尋或下載包,將包安裝到當前目錄的 node_modules 子目錄下。

如果你熟悉 Ruby 的 gem 或者 Python 的 pip ,你會發現 npm 與它們的行為不同, gem 或 pip 總是以全域性模式安裝,使包可以供所有的程式使用,而 npm 預設會把包安裝到當前目錄下。這反映了 npm 不同的設計哲學。如果把包安裝到全域性,可以提供程式的重複利用程度,避免同樣的內容的多分副本,但壞處是難以處理不同的版本依賴。如果把包安裝到當前目錄,或者說本地,則不會有不同程式依賴不同版本的包的衝突問題,同時還減輕了包作者的 API 相容性壓力,但缺陷則是同一個包可能會被安裝許多次。

我們在使用 supervisor 的時候使用了 npm install -g supervisor 命令,就是以全域性模式安裝 supervisor 。

這裡注意一點的就是, supervisor 必須安裝到全域性,如果你不安裝到全域性,錯誤命令會提示你安裝到全域性。如果不想安裝到預設的全域性,也可以自己修改全域性路徑到當前路徑 npm config set prefix “路徑” 安裝完以後就可以用 supervisor 來啟動服務了。
supervisor 可以幫助你實現這個功能,它會監視你對程式碼的驅動,並自動重啟 Node 。

一般來說,全域性安裝只適用於工具模組,比如 eslint 和 gulp 。關於使用全域性模式,多數時候並不是因為許多程式都有可能用到了它,為了減少多重副本而使用全域性模式,而是因為 本地模式不會註冊 PATH 環境變數。
“本地安裝”指的是將一個模組下載到當前專案的 node_modules 子目錄,然後只有在專案目錄之中,才能呼叫這個模組。

本地模式和全域性模式的特點如下:

模式 可通過 require 使用 註冊 PATH
本地模式 是 否
全域性模式 否 是

1
2
3
4
5
6

本地安裝

$ npm install

全域性安裝

$ sudo npm install -global
$ sudo npm install -g
npm install 也支援直接輸入 Github 程式碼庫地址。

1
2
$ npm install git://github.com/package/path.git
$ npm install git://github.com/package/path.git#0.1.0
安裝之前,npm install 會先檢查,node_modules 目錄之中是否已經存在指定模組。如果存在,就不再重新安裝了,即使遠端倉庫已經有了一個新版本,也是如此。

如果你希望,一個模組不管是否安裝過, npm 都要強制重新安裝,可以使用 -f 或 --force 引數。

1
$ npm install --force
注:不推薦全域性安裝 webpack。這會將您專案中的 webpack 鎖定到指定版本,並且在使用不同的 webpack 版本的專案中,可能會導致構建失敗。
安裝不同版本

install 命令總是安裝模組的最新版本,如果要安裝模組的特定版本,可以在模組名後面加上 @ 和版本號。

1
2
3
$ npm install [email protected]
$ npm install [email protected]
$ npm install [email protected]">=0.1.0 <0.2.0"
install 命令可以使用不同引數,指定所安裝的模組屬於哪一種性質的依賴關係,即出現在 packages.json 檔案的哪一項中。

–save:模組名將被新增到 dependencies,可以簡化為引數-S。
–save-dev:模組名將被新增到 devDependencies,可以簡化為引數-D。
1
2
3
4
5
$ npm install sax --save
$ npm install node-tap --save-dev

或者

$ npm install sax -S
$ npm install node-tap -D
dependencies 依賴

這個可以說是我們 npm 核心一項內容,依賴管理,這個物件裡面的內容就是我們這個專案所依賴的 js 模組包。下面這段程式碼表示我們依賴了 markdown-it 這個包,版本是 ^8.1.0 ,代表最小依賴版本是 8.1.0 ,如果這個包有更新,那麼當我們使用 npm install 命令的時候, npm 會幫我們下載最新的包。當別人引用我們這個包的時候,包內的依賴包也會被下載下來。

1
2
3
“dependencies”: {
“markdown-it”: “^8.1.0”
}
devDependencies 開發依賴

在我們開發的時候會用到的一些包,只是在開發環境中需要用到,但是在別人引用我們包的時候,不會用到這些內容,放在 devDependencies 的包,在別人引用的時候不會被 npm 下載。

1
2
3
4
5
6
7
8
9
10
11
“devDependencies”: {
“autoprefixer”: “^6.4.0”,
“babel-preset-es2015”: “^6.0.0”,
“babel-preset-stage-2”: “^6.0.0”,
“babel-register”: “^6.0.0”,
“webpack”: “^1.13.2”,
“webpack-dev-middleware”: “^1.8.3”,
“webpack-hot-middleware”: “^2.12.2”,
“webpack-merge”: “^0.14.1”,
“highlightjs”: “^9.8.0”
}
當你有了一個完整的 package.json檔案的時候,就可以讓人一眼看出來,這個模組的基本資訊,和這個模組所需要依賴的包。我們可以通過 npm install 就可以很方便的下載好這個模組所需要的包。

npm install 預設會安裝 dependencies 欄位和 devDependencies 欄位中的所有模組,如果使用 --production 引數,可以只安裝 dependencies 欄位的模組。

1
2
3
$ npm install --production

或者

$ NODE_ENV=production npm install
一旦安裝了某個模組,就可以在程式碼中用 require 命令載入這個模組。

1
2
var backbone = require(‘backbone’)
console.log(backbone.VERSION)
npm run

npm 不僅可以用於模組管理,還可以用於執行指令碼。package.json 檔案有一個 scripts 欄位,可以用於指定指令碼命令,供 npm 直接呼叫。
package.json 檔案內容:

1
2
3
4
5
6
7
8
9
10
11
12
{
“name”: “myproject”,
“devDependencies”: {
“jshint”: “latest”,
“browserify”: “latest”,
“mocha”: “latest”
},
“scripts”: {
“lint”: “jshint **.js”,
“test”: “mocha test/”
}
}
scripts 指令碼

顧名思義,就是一些指令碼程式碼,可以通過 npm run script-key 來呼叫,例如在這個 package.json 的資料夾下使用 npm run dev 就相當於運行了 node build/dev-server.js 這一段程式碼。使用 scripts 的目的就是為了把一些要執行的程式碼合併到一起,使用 npm run 來快速的執行,方便省事。
npm run 是 npm run-script 的縮寫,一般都使用前者,但是後者可以更好的反應這個命令的本質。

1
2
3
4
5
6
7
8
9
// 指令碼
“scripts”: {
“dev”: “node build/dev-server.js”,
“build”: “node build/build.js”,
“docs”: “node build/docs.js”,
“build-docs”: “npm run docs & git checkout gh-pages & xcopy /sy dist\* . & git add . & git commit -m ‘auto-pages’ & git push & git checkout master”,
“build-publish”: “rmdir /S /Q lib & npm run build &git add . & git commit -m auto-build & npm version patch & npm publish & git push”,
“lint”: “eslint --ext .js,.vue src”
}
npm run 如果不加任何引數,直接執行,會列出 package.json 裡面所有可以執行的指令碼命令。
npm 內建了兩個命令簡寫, npm test 等同於執行 npm run test ,npm start 等同於執行 npm run start。

1
“build”: “npm run build-js && npm run build-css”
上面的寫法是先執行 npm run build-js ,然後再執行 npm run build-css ,兩個命令中間用 && 連線。如果希望兩個命令同時平行執行,它們中間可以用 & 連線。

寫在 scripts 屬性中的命令,也可以在 node_modules/.bin 目錄中直接寫成 bash 指令碼。下面是一個 bash 指令碼。

1
2
3
4
#!/bin/bash

cd site/main
browserify browser/main.js | uglifyjs -mc > static/bundle.js
假定上面的指令碼檔名為 build.sh ,並且許可權為可執行,就可以在 scripts 屬性中引用該檔案。

1
“build-js”: “bin/build.sh”
pre- 和 post- 指令碼

npm run 為每條命令提供了 pre- 和 post- 兩個鉤子( hook )。以 npm run lint 為例,執行這條命令之前, npm 會先檢視有沒有定義 prelint 和 postlint 兩個鉤子,如果有的話,就會先執行 npm run prelint ,然後執行 npm run lint ,最後執行 npm run postlint 。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
“name”: “myproject”,
“devDependencies”: {
“eslint”: “latest”
“karma”: “latest”
},
“scripts”: {
“lint”: “eslint --cache --ext .js --ext .jsx src”,
“test”: “karma start --log-leve=error karma.config.js --single-run=true”,
“pretest”: “npm run lint”,
“posttest”: “echo ‘Finished running tests’”
}
}
上面程式碼是一個 package.json 檔案的例子。如果執行 npm test,會按下面的順序執行相應的命令。

pretest
test
posttest
如果執行過程出錯,就不會執行排在後面的指令碼,即如果 prelint 指令碼執行出錯,就不會接著執行 lint 和 postlint 指令碼。

npm bin

npm bin 命令顯示相對於當前目錄的,Node 模組的可執行指令碼所在的目錄(即 .bin 目錄)。

1
2
3

專案根目錄下執行

$ npm bin
./node_modules/.bin
建立全域性連結
npm 提供了一個有趣的命令 npm link,它的功能是在本地包和全域性包之間建立符號連結。我們說過使用全域性模式安裝的包不能直接通過 require 使用。但通過 npm link 命令可以打破這一限制。舉個例子,我們已經通過 npm install -g express 安裝了 express ,這時在工程的目錄下執行命令:npm link express ./node_modules/express -> /user/local/lib/node_modules/express
我們可以在 node_modules 子目錄中發現一個指向安裝到全域性的包的符號連結。通過這種方法,我們就可以把全域性包當做本地包來使用了。
除了將全域性的包連結到本地以外,使用 npm link 命令還可以將本地的包連結到全域性。使用方法是在包目錄(package.json 所在目錄)中執行 npm link 命令。如果我們要開發一個包,利用這種方法可以非常方便地在不同的工程間進行測試。

建立包
包是在模組基礎上更深一步的抽象,Node 的包類似於 C/C++ 的函式庫或者 Java 、.Net 的類庫。它將某個獨立的功能封裝起來,用於釋出、更新、依賴管理和版本控制。Node 根據 CommonJS 規範實現了包機制,開發了 npm 來解決包的釋出和獲取需求。
Node 的包是一個目錄,其中包含了一個 JSON 格式的包說明檔案 package.json。嚴格符合 CommonJS 規範的包應該具備以下特徵:

package.json 必須在包的頂層目錄下;
二進位制檔案應該在 bin 目錄下;
JavaScript 程式碼應該在 lib 目錄下;
文件應該在 doc 目錄下;
單元測試應該在 test 目錄下。
Node 對包的要求並沒有這麼嚴格,只要頂層目錄下有 package.json,並符合一些規範即可。當然為了提高相容性,我們還是建議你在製作包的時候,嚴格遵守 CommonJS 規範。

我們也可以把資料夾封裝為一個模組,即所謂的包。包通常是一些模組的集合,在模組的基礎上提供了更高層的抽象,相當於提供了一些固定介面的函式庫。通過定製 package.json,我們可以建立更復雜,更完善,更符合規範的包用於釋出。

Node 在呼叫某個包時,會首先檢查包中 packgage.json 檔案的 main 欄位,將其作為包的介面模組,如果 package.json 或 main 欄位不存在,會嘗試尋找 index.js 或 index.node 作為包的介面。

package.json 是 CommonJS 規定的用來描述包的檔案,完全符合規範的 package.json 檔案應該含有以下欄位:
name: 包的名字,必須是唯一的,由小寫英文字母、數字和下劃線組成,不能包含空格。
description: 包的簡要說明。
version: 符合語義化版本識別規範的版本字串。
keywords: 關鍵字陣列,通常用於搜尋。
maintainers: 維護者陣列,每個元素要包含 name 、 email(可選)、 web(可選)欄位。
contributors: 貢獻者陣列,格式與 maintainers 相同。包的作者應該是貢獻者陣列的第一個元素。
bugs: 提交 bug 的地址,可以是網址或者電子郵件地址。
licenses: 許可證陣列,每個元素要包含 type (許可證的名稱)和 url(連結到許可證文字的地址)欄位。
repositories: 倉庫託管地址陣列,每個元素要包含 type (倉庫的型別,如 git)、URL(倉庫的地址)和 path(相對於倉庫的路徑,可選)欄位。
dependencies: 包的依賴,一個關聯陣列,由包名稱和版本號組成。

包的釋出
通過使用 npm init 可以根據互動式回答產生一個符合標準的 package.json。建立一個 index.js 作為包的介面,一個簡單的包就製作完成了。
在釋出前,我們還需要獲得一個賬號用於今後維護自己的包,使用 npm adduser 根據提示完成賬號的建立
完成後可以使用 npm whoami 檢測是否已經取得了賬號。
接下來,在 package.json 所在目錄下執行 npm publish,稍等片刻就可以完成釋出了,開啟瀏覽器,訪問 NPM搜尋 就可以找到自己剛剛釋出的包了。現在我們可以在世界的任意一臺計算機上使用 npm install neveryumodule 命令來安裝它。
如果你的包將來有更新,只需要在 package.json 檔案中修改 version 欄位,然後重新使用 npm publish命令就行了。
如果你對已釋出的包不滿意,可以使用 npm unpublish 命令來取消釋出。

安裝模組時遇到的問題

npm安裝包報錯

解決方案參考網址:https://www.cnblogs.com/nurdun/p/6824480.html

1.通過config命令

npm config set registry http://registry.cnpmjs.org
npm info underscore (如果上面配置正確這個命令會有字串response)
2.命令列指定

npm --registry http://registry.cnpmjs.org info underscore

需要說明的是: json 檔案不能有註釋

參考連結
http://javascript.ruanyifeng.com/nodejs/npm.html © 著作權歸原作者所有