npm指南
什么是 NPM
npm?之于?Node?,就像?pip?之于?Python?,?gem?之于?Ruby?,?pear?之于?PHP?。
npm?是?Node?官方提供的包管理工具,他已經成了?Node?包的標準發布平臺,用于?Node?包的發布、傳播、依賴控制。
npm?提供了命令行工具,使你可以方便地下載、安裝、升級、刪除包,也可以讓你作為開發者發布并維護包。
為什么要使用 NPM
npm?是隨同?Node?一起安裝的包管理工具,能解決?Node?代碼部署上的很多問題,常見的場景有以下幾種:
- 允許用戶從?npm?服務器下載別人編寫的第三方包到本地使用。
- 允許用戶從?npm?服務器下載并安裝別人編寫的命令行程序到本地使用。
- 允許用戶將自己編寫的包或命令行程序上傳到?npm?服務器供別人使用。
npm?的背后,是基于?CouchDB?的一個數據庫,詳細記錄了每個包的信息,包括作者、版本、依賴、授權信息等。它的一個很重要的作用就是:將開發者從繁瑣的包管理工作(版本、依賴等)中解放出來,更加專注于功能的開發。
如何使用 NPM
安裝
npm?不需要單獨安裝。在安裝?Node?的時候,會連帶一起安裝?npm?。但是,Node?附帶的?npm?可能不是最新版本,最后用下面的命令,更新到最新版本。
| 1 | $ sudo npm install npm@latest -g |
如果是 Window 系統使用以下命令即可:
| 1 | npm install npm -g |
也就是使用?npm?安裝自己。之所以可以這樣,是因為?npm?本身與?Node?的其他模塊沒有區別。
然后,運行下面的命令,查看各種信息。
| 1 2 3 4 5 6 7 8 9 10 11 |
使用
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 |
上面命令返回一個?JavaScript?對象,包含了?underscore?模塊的詳細信息。這個對象的每個成員,都可以直接從?info?命令查詢。
| 1 2 3 4 5 | $ npm $ npm $ npm |
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?子目錄,然后只有在項目目錄之中,才能調用這個模塊。
本地模式和全局模式的特點如下:
| 本地模式 | 是 | 否 |
| 全局模式 | 否 | 是 |
| 1 2 3 4 5 6 | # 本地安裝 $ npm install <package name> # 全局安裝 $ sudo npm install -global <package name> $ sudo npm install -g <package name> |
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 <packageName> --force |
安裝不同版本
install?命令總是安裝模塊的最新版本,如果要安裝模塊的特定版本,可以在模塊名后面加上?@?和版本號。
| 1 2 3 | $ 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。
| 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 | 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,會按下面的順序執行相應的命令。
如果執行過程出錯,就不會執行排在后面的腳本,即如果?prelint?腳本執行出錯,就不會接著執行?lint?和?postlint?腳本。
npm bin
npm bin?命令顯示相對于當前目錄的,Node?模塊的可執行腳本所在的目錄(即?.bin?目錄)。
| 1 2 3 |
創建全局鏈接
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://www.cnblogs.com/lzcblog/p/9863816.html
總結
- 上一篇: EF Core 生成数据库
- 下一篇: 201771010102 常惠琢 《2