NPM 學習筆記整理

什么是 NPM

npm之于Node,就像pip之于Python,gem之于Ruby,composer之于PHP。

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

為什么要使用 NPM

npm是隨同Node一起安裝的包管理工具,能解決Node代碼部署上的很多問題,常見的場景有以下幾種:

允許用戶從npm服務器下載別人編寫的第三方包到本地使用。

允許用戶從npm服務器下載并安裝別人編寫的命令行程序到本地使用。

允許用戶將自己編寫的包或命令行程序上傳到npm服務器供別人使用。

npm的背后,是基于CouchDB的一個數據庫,詳細記錄了每個包的信息,包括作者、版本、依賴、授權信息等。它的一個很重要的作用就是:將開發者從繁瑣的包管理工作(版本、依賴等)中解放出來,更加專注于功能的開發。

如何使用 NPM

安裝

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

$ sudo npm install npm@latest -g

如果是 Window 系統使用以下命令即可:

npm install npm -g

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

然后,運行下面的命令,查看各種信息。

#查看 npm 命令列表$ npmhelp#查看各個命令的簡單用法$ npm -l#查看 npm 的版本$ npm -v#查看 npm 的配置$ npm config list -l

使用

npm init

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

$ npm init -y

npm set

npm set用來設置環境變量

$ npmsetinit-author-name'Your name'$ npmsetinit-author-email'Your email'$ npmsetinit-author-url'http://yourdomain.com'$ npmsetinit-license'MIT'

上面命令等于為npm init設置了默認值,以后執行npm init的時候,package.json的作者姓名、郵件、主頁、許可證字段就會自動寫入預設的值。這些信息會存放在用戶主目錄的~/.npmrc文件,使得用戶不用每個項目都輸入。如果某個項目有不同的設置,可以針對該項目運行npm config。

npm info

npm info命令可以查看每個模塊的具體信息。比如,查看underscore模塊的信息。

$ npm info underscore

上面命令返回一個JavaScript對象,包含了underscore模塊的詳細信息。這個對象的每個成員,都可以直接從info命令查詢。

$ npm info underscore description

$ npm info underscore homepage

$ npm info underscore version

npm search

npm search命令用于搜索npm倉庫,它后面可以跟字符串,也可以跟正則表達式。

$ npm search<搜索詞>

npm list

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

$ 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

本地模式是否

全局模式否是

#本地安裝$ npm install#全局安裝$ sudo npm install -global$ sudo npm install -g

npm install也支持直接輸入Github代碼庫地址。

$ 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參數。

$ npm install--force

安裝不同版本

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

$ npm install sax@latest$ npm install sax@0.1.1$ npm install sax@">=0.1.0 <0.2.0"

install命令可以使用不同參數,指定所安裝的模塊屬于哪一種性質的依賴關系,即出現在packages.json文件的哪一項中。

--save:模塊名將被添加到 dependencies,可以簡化為參數-S。 --save-dev:模塊名將被添加到 devDependencies,可以簡化為參數-D。

$ 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會幫我們下載最新的包。當別人引用我們這個包的時候,包內的依賴包也會被下載下來。

"dependencies":{"markdown-it":"^8.1.0"}

devDependencies 開發依賴

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

"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字段的模塊。

$ npm install --production#或者$ NODE_ENV=production npm install

一旦安裝了某個模塊,就可以在代碼中用require命令加載這個模塊。

varbackbone=require('backbone')console.log(backbone.VERSION)

npm run

npm不僅可以用于模塊管理,還可以用于執行腳本。package.json文件有一個scripts字段,可以用于指定腳本命令,供npm直接調用。package.json文件內容:

{"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的縮寫,一般都使用前者,但是后者可以更好的反應這個命令的本質。

//腳本"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。

"build":"npm run build-js && npm run build-css"

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

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

#!/bin/bashcdsite/mainbrowserify browser/main.js|uglifyjs -mc>static/bundle.js

假定上面的腳本文件名為build.sh,并且權限為可執行,就可以在scripts屬性中引用該文件。

"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。

{"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目錄)。

#項目根目錄下執行$ 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命令來取消發布。

*需要說明的是: `json` 文件不能有注釋*

參考鏈接

https://blog.ihoey.com/posts/Node/2017-05-10-npm.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,914評論 2 372

推薦閱讀更多精彩內容

  • npm是什么 NPM的全稱是Node Package Manager,是隨同NodeJS一起安裝的包管理和分發工具...
    build1024閱讀 7,919評論 0 9
  • 本文內容基于 npm 4.0.5 概述 npm (node package manager),即 node 包管理...
    靜默虛空閱讀 2,159評論 0 8
  • npm介紹 包管理器(Package Manager) npm 最初它只是被稱為 Node Package Man...
    faner閱讀 26,949評論 0 16
  • 描述 npm從以下來源獲取配置值,按優先級排序: 命令行標記 在命令行上放置--foo bar設置foo配置參數為...
    竹天亮閱讀 44,194評論 0 8
  • 初一的時候我13歲,第一次有男生跟我告白,然后我以不喜歡他的發型為由拒絕了;大二的時候我20歲,第一次跟喜歡的...
    慕徐閱讀 904評論 0 0