npm
1. 什么是npm
npm是Node官方提供的包管理工具,它已經(jīng)成了Node包的標(biāo)準(zhǔn)發(fā)布平臺(tái),用于Node包的發(fā)布、傳播、依賴(lài)控制。npm提供了命令行工具,使你可以方便地下載、安裝、升級(jí)、刪除包,也可以讓你作為開(kāi)發(fā)者發(fā)布并維護(hù)包。
2. 安裝npm
npm不需要單獨(dú)安裝。在安裝Node的時(shí)候,會(huì)連帶一起安裝npm。
但是,Node附帶的npm可能不是最新版本,最后用下面的命令,更新到最新版本。
$ sudo npm install npm@latest -g
安裝完成查看 npm 的版本
$ npm -v
# 6.4.1
3. npm常用命令
3.1 安裝npm包
有兩種方式用來(lái)安裝 npm 包:本地安裝和全局安裝。至于選擇哪種方式來(lái)安裝,取決于我們?nèi)绾问褂眠@個(gè)包。
如果你自己的模塊依賴(lài)于某個(gè)包(比如通過(guò) Node.js 的require加載),那么你應(yīng)該選擇本地安裝,這種方式也是npm install命令的默認(rèn)行為。 如果你想將包作為一個(gè)命令行工具,比如 creat-react-app,Vue Cli,那么你應(yīng)該選擇全局安裝。
3.1.1 本地安裝
使用npm install進(jìn)行本地安裝,可以簡(jiǎn)寫(xiě)為npm i
npm i <package_name>
上述命令執(zhí)行之后將會(huì)在當(dāng)前的目錄下創(chuàng)建一個(gè)node_modules 的目錄(如果不存在的話),然后將下載的包保存到這個(gè)目錄下。
3.1.2 全局安裝
使用npm i -g進(jìn)行全局安裝
npm i -g
3.1.3 安裝不同版本
npm i <package_name>@latest
npm i <package_name>@1.1.1
npm i <package_name>@">=1.1.0 <1.2.0"
3.1.4 –save與--save-dev參數(shù)
使用npm i會(huì)安裝dependencies字段和devDependencies字段中的所有模塊
-
--save:模塊名將被添加到dependencies,可以簡(jiǎn)化為參數(shù)-S,npm 5.x+版本默認(rèn)添加此參數(shù) -
--save-dev: 模塊名將被添加到devDependencies,可以簡(jiǎn)化為參數(shù)-D
將運(yùn)行時(shí)的依賴(lài)安裝到
dependencies,將開(kāi)發(fā)時(shí)的依賴(lài)安裝到devDependencies。
dependencies下記錄的是項(xiàng)目在運(yùn)行時(shí)必須依賴(lài)的插件,常見(jiàn)的例如vue react jquery等,
即使項(xiàng)目打包好了、上線了,這些也是需要用的,否則程序無(wú)法正常執(zhí)行。
devDependencies下記錄的是項(xiàng)目在開(kāi)發(fā)過(guò)程中使用的插件,例如我們開(kāi)發(fā)過(guò)程中需要使用webpack打包,
但是一旦項(xiàng)目打包發(fā)布、上線了之后,webpack就都沒(méi)有用了。
一旦將包安裝到node_modules 目錄中,你就可以使用它了。
3.2 更新與卸載npm包
3.2.1 更新npm包
可以使用npm outdate命令查詢(xún)已安裝過(guò)的包中是否有過(guò)時(shí)版本
$ npm outdated
Package Current Wanted Latest Location
glob 5.0.15 5.0.15 6.0.1 test-outdated-output
nothingness 0.0.3 git git test-outdated-output
npm 3.5.1 3.5.2 3.5.1 test-outdated-output
local-dev 0.0.3 linked linked test-outdated-output
once 1.3.2 1.3.3 1.3.3 test-outdated-output
使用npm update命令,可以簡(jiǎn)寫(xiě)為npm up
# 本地更新
npm up <package_name>
# 使用 -S 參數(shù)更新package.json里面dependencies模塊的版本號(hào)
npm up <package_name> -S
# 使用 -D 參數(shù)更新package.json里面devDependencies模塊的版本號(hào)
npm up <package_name> -D
# 全局更新
npm up -g <package_name>
3.2.2 卸載npm包
使用npm uninstall命令,可以簡(jiǎn)寫(xiě)為npm un
# 卸載本地模塊
$ npm un <package_name>
# 卸載全局模塊
$ npm un -g <package_name>
3.3 npm run指令
npm不僅可以用于模塊管理,還可以用于執(zhí)行腳本。package.json文件有一個(gè)scripts字段,可以用于指定腳本命令,供npm直接調(diào)用。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
}
npm start
npm run build
npm內(nèi)置了兩個(gè)命令簡(jiǎn)寫(xiě),
npm test等同于執(zhí)行npm run test,npm start等同于執(zhí)行npm run start。
npm run為每條命令提供了pre-和post-兩個(gè)鉤子(hook),
以npm run test為例,執(zhí)行這條命令之前,npm會(huì)先查看有沒(méi)有定義pretest和posttest兩個(gè)鉤子,
如果有的話,就會(huì)先執(zhí)行npm run pretest,然后執(zhí)行npm run test,最后執(zhí)行npm run posttest。
如果執(zhí)行過(guò)程出錯(cuò),就不會(huì)執(zhí)行排在后面的腳本,即如果pretest腳本執(zhí)行出錯(cuò),就不會(huì)接著執(zhí)行test和posttest腳本。
例子
{
"test": "karma start",
"test:lint": "eslint . --ext .js --ext .jsx",
"pretest": "npm run test:lint"
}
# 上面代碼中,在運(yùn)行npm run test之前,會(huì)自動(dòng)檢查代碼,即運(yùn)行npm run test:lint命令。
下面是一些常見(jiàn)的pre-和post-腳本。
-
prepublish,postpublish -
preinstall,postinstall -
preuninstall,postuninstall -
preversion,postversion -
pretest,posttest -
prestop,poststop -
prestart,poststart -
prerestart,postrestart
另外,不能在pre腳本之前再加pre,即prepretest腳本不起作用。
注意,即使npm可以自動(dòng)運(yùn)行pre和post腳本,也可以手動(dòng)執(zhí)行它們。
4. 如何發(fā)布npm包
通常發(fā)包的倉(cāng)庫(kù)地址為npm倉(cāng)庫(kù)或者公司內(nèi)部私有 npm 倉(cāng)庫(kù),這里以發(fā)布到npm倉(cāng)庫(kù)為例
4.1 npm init初始化package.json文件
npm init
# 使用npm init -y可以快速生成默認(rèn)的package.json文件
# 根據(jù)提示填寫(xiě),其中name與version為必填
About to write to D:\luotongzhou\npm-example\package.json:
{
"name": "npm-example-luotongzhou",
"version": "1.0.0",
"description": "npm-example",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "luotongzhou",
"license": "ISC"
}
如果是將包發(fā)布到私有倉(cāng)庫(kù)需要在package.json修改發(fā)布地址
# packages.json
"publishConfig": {
"registry": "http://localhost/repository/npm-hosted/"
}
4.2 創(chuàng)建模塊入口文件
在當(dāng)前目錄下創(chuàng)建index.js文件,該文件為模塊的入口文件,可在npm init或package.json文件中設(shè)置
# index.js
module.exports.printMsg = function() {
console.log("my first npm package")
}
4.3 發(fā)布npm包
4.3.1 注冊(cè)npm賬號(hào)
注冊(cè)npm賬號(hào)有兩種方式,一種是在npm官網(wǎng)注冊(cè),另外一種是使用npm adduser命令注冊(cè)
npm adduser
Username: # 輸入用戶(hù)名
Password:# 輸入密碼,默認(rèn)不可見(jiàn)
Email:# 輸入郵箱
# 注冊(cè)完成后顯示
Logged in as <your username> on http://registry.npmjs.org/.
4.3.2 將包發(fā)布到npm倉(cāng)庫(kù)
使用npm publish命令將包發(fā)布到npm倉(cāng)庫(kù)
npm publish
# 發(fā)布完成后顯示
+ npm-example-luotongzhou@1.0.0
發(fā)布時(shí)可能報(bào)以下錯(cuò)誤:
1.no_perms Private mode enable, only admin can publish this module
使用cnpm的原因,設(shè)置回原本的就可以了
npm config set registry http://registry.npmjs.org
發(fā)布完成之后,如果還想回到之前的cnpm,使用下面的命令
npm config set registry https://registry.npm.taobao.org
2.npm ERR! publish Failed PUT 403
You do not have permission to publish "xxxx". Are you logged in
as the correct user? : xxxx
這個(gè)錯(cuò)誤是package.json中的name與npm倉(cāng)庫(kù)中的包名重復(fù)了,修改package.json中的name為全網(wǎng)唯一就好了
3.npm ERR! publish Failed PUT 403
npm ERR! you must verify your email before publishing a new package
沒(méi)有驗(yàn)證郵箱的原因,去注冊(cè)npm賬號(hào)的郵箱找到驗(yàn)證的郵件點(diǎn)擊驗(yàn)證鏈接就行了,鏈接有可能過(guò)期,官網(wǎng)上登錄后可以重新發(fā)送驗(yàn)證郵件
4.4 拉取并使用發(fā)布的包
新建一個(gè)文件夾,使用npm i拉取剛才發(fā)布的包
npm i npm-example-luotongzhou
創(chuàng)建index.js文件
var test = require('npm-example-luotongzhou')
test.printMsg();
運(yùn)行node index.js命令
D:\luotongzhou\npm>node index.js
my first npm package # 打印出結(jié)果
4.5 更新已發(fā)布的包
更新已發(fā)布的包需要修改包的版本號(hào)即packages.json的version值,可以直接修改packages.json文件中version的版本號(hào)。但為了使用語(yǔ)義化的版本不建議直接修改version的值,可以使用npm version命令進(jìn)行版本更新
# 修改printMsg方法里的內(nèi)容
module.exports.printMsg = function() {
console.log("my first npm package has updated")
}
# 更新版本
npm version <update_type>
常用update_type有 major | minor | patch
# 示例
npm version patch
v1.0.1
npm version minor
v1.1.0
npm version major
v2.0.0
繼續(xù)npm publish發(fā)布就好了
之后只需要在引入該包的項(xiàng)目中npm up更新該包即可。
5. npm配置
5.1 npm config
npm cli 提供了 npm config 命令進(jìn)行 npm 相關(guān)配置,通過(guò) npm config ls -l 可查看 npm 的所有配置,包括默認(rèn)配置。
修改配置的命令為npm config set <key> <value>, 我們使用相關(guān)的常見(jiàn)重要配置:
-
proxy,https-proxy: 指定 npm 使用的代理 -
registry指定 npm 下載安裝包時(shí)的源,默認(rèn)為https://registry.npmjs.org/可以指定為私有registry源 -
package-lock指定是否默認(rèn)生成package-lock文件,建議保持默認(rèn) true -
savetrue/false 指定是否在npm install 后保存包為dependencies, npm 5 起默認(rèn)為 true
例:
npm config set registry https://registry.npm.taobao.org
# 切換淘寶鏡像
刪除指定的配置項(xiàng)命令為 npm config delete <key>.
5.2 npmrc 文件
除了使用 CLI 的 npm config 命令顯示更改 npm 配置,還可以通過(guò) npmrc 文件直接修改配置。
這樣的 npmrc 文件優(yōu)先級(jí)由高到低包括:
- 工程內(nèi)配置文件:
/path/to/my/project/.npmrc - 用戶(hù)級(jí)配置文件:
~/.npmrc - 全局配置文件:
$PREFIX/etc/npmrc(即npm config get globalconfig輸出的路徑) - npm內(nèi)置配置文件:
/path/to/npm/npmrc
通過(guò)這個(gè)機(jī)制,我們可以方便地在工程根目錄創(chuàng)建一個(gè).npmrc 文件來(lái)共享需要在團(tuán)隊(duì)間共享的 npm 運(yùn)行相關(guān)配置。比如如果我們?cè)诠緝?nèi)網(wǎng)環(huán)境下需通過(guò)代理才可訪問(wèn) registry.npmjs.org 源,或需訪問(wèn)內(nèi)網(wǎng)的 registry, 就可以在工作項(xiàng)目下新增.npmrc 文件并提交代碼庫(kù)。
proxy = http://proxy.example.com/
https-proxy = http://proxy.example.com/
registry = http://registry.example.com/