你應(yīng)該知道的 NPM 知識(shí)都在這!
為什么寫這篇文章
很多 Node.js 開發(fā)者,都知道有 package.json 這個(gè)文件,也多少都了解一些 npm 知識(shí),但是可能沒有系統(tǒng)的學(xué)習(xí)過,這部分的知識(shí)對(duì)于開發(fā)一個(gè) ?cli 工具,發(fā)布自己的 npm 包都很常用,開發(fā)中也會(huì)經(jīng)常用到npm script內(nèi)容,系統(tǒng)的學(xué)習(xí)一下確實(shí)會(huì)有所幫助,上面三個(gè)場景如果你都用不到,配置上節(jié)約時(shí)間,知其所以然也是有必要的!
本文你能學(xué)到哪些?

文章比較長,希望耐心看完!
寫文本的目標(biāo):希望再遇到
package.json,npm相關(guān)的問題,不用再去搜索,一篇文章全覆蓋,不一定全掌握,知道我這里都有,需要時(shí)候能直接來查就好了,也為了方便自己后面查閱。(本文主要講的部分是npm script,個(gè)人認(rèn)為很常用,一些文章都沒有講)
好了,開始我們的正文學(xué)習(xí)吧。
package.json 如何產(chǎn)生的
npm init
npm init 命令用來初始化一個(gè)簡單的 package.json 文件,執(zhí)行該命令后終端會(huì)依次詢問 name, version, description 等字段。
npm init 默認(rèn)執(zhí)行行為
我們?cè)趫?zhí)行 npm init 的時(shí)候,會(huì)有一個(gè)初始化 pacakge.json 過程,然后一路回車,其實(shí)可以直接使用 npm init --yes 在命令后追加 --yes 參數(shù)即可,其作用與一路回車相同,這樣生成的文件中就包含 package.json 文件
自定義 npm init 行為
npm init 命令的原理并不復(fù)雜,調(diào)用 shell 腳本,輸出一個(gè)初始化的 package.json 文件。所以相應(yīng)地,自定義 npm init 命令的實(shí)現(xiàn)方式也很簡單,在電腦 npmStudy 目錄創(chuàng)建一個(gè) .npm-init.js 即可,該文件的 module.exports 即為 package.json 配置內(nèi)容,需要獲取用戶輸入時(shí)候,使用 prompt() 方法即可。例如編寫這樣的 ~/.npm-init.js
const?desc?=?prompt('description?',?'A?new?package...')
const?bar?=?prompt('bar?',?'')
const?count?=?prompt('count?',?'42')
module.exports?=?{
??key:?'value',
??foo:?{
????bar:?bar,
????count:?count
??},
??name:?prompt('name?',?process.cwd().split('/').pop()),
??version:?prompt('version?',?'0.1.0'),
??description:?desc,
??main:?'index.js',
}
然后在 /npmStudy 目錄下執(zhí)行 npm init 會(huì)出現(xiàn)下圖中對(duì)一系列操作

然后生成 package.json 文件。到這里一個(gè) npm init 簡單自定義過程結(jié)束,知道了兩種生成 pacakge.json 的方式
package.json 中的常規(guī)屬性
對(duì)于常規(guī)屬性都知道的可以忽略,繼續(xù)往下看 npm script 主要想講的部分。
npm 中的依賴包
這里只說我們常用的兩個(gè)依賴包 ?dependenices 和 devDependenices,其它的一些依賴包只有作為包的發(fā)布者才會(huì)用到,需要的小伙伴自行查看文檔。
dependenices
通過命令npm install/i packageName -S/--save把包裝在此依賴項(xiàng)里。如果沒有指定版本,直接寫一個(gè)包的名字,則安裝當(dāng)前npm倉庫中這個(gè)包的最新版本。如果要指定版本的,可以把版本號(hào)寫在包名后面,比如npm i [email protected] -S。
從
npm 5.x開始,可以不用手動(dòng)添加-S/--save指令,直接執(zhí)行npm i packageName把依賴包添加到dependencies中去。
?"dependencies":?{
??????"lodash":?"^4.17.13",
??????"moment":?"^2.24.0",
?}
devDependenices
有一些包有可能你只是在開發(fā)環(huán)境中用到,例如你用于檢測代碼規(guī)范的 eslint ,用于進(jìn)行測試的 jest ,用戶使用你的包時(shí)即使不安裝這些依賴也可以正常運(yùn)行,反而安裝他們會(huì)耗費(fèi)更多的時(shí)間和資源,所以你可以把這些依賴添加到 devDependencies 中,這些依賴照樣會(huì)在你本地進(jìn)行 npm install 時(shí)被安裝和管理,但是不會(huì)被安裝到生產(chǎn)環(huán)境:
?"devDependencies":?{
??????"jest":?"^24.3.1",
??????"eslint":?"^6.1.0",
?}
二者簡單對(duì)比
devDependencies主要是存放用于本地開發(fā)的dependencies會(huì)在我們開發(fā)的時(shí)候帶到線上-D會(huì)添加到devDependencies里面,-S會(huì)添加到dependencies--save-dev也會(huì)添加到devDependencies--save會(huì)添加到dependencies從 npm 5.x開始,如果什么參數(shù)都不帶,那么默認(rèn)添加到dependencies中
??#?添加到?devDependencies
??npm?install?-D?xxxx
??#?添加到?dependencies
??npm?install?-S?xxxx
bin
?"bin":?{
????"vm2":?"./bin/vm2"
??},
bin 字段指定了各個(gè)內(nèi)部命令對(duì)應(yīng)的可執(zhí)行文件的位置。如果全局安裝模塊報(bào),npm 會(huì)使用符號(hào)鏈接把可執(zhí)行文件鏈接到 /usr/local/bin,如果項(xiàng)目中安裝,會(huì)鏈接到 ./node_modules/.bin/。
上面的這種當(dāng)你的包安裝到全局時(shí):npm 會(huì)在 /usr/local/bin 下創(chuàng)建一個(gè)以 vm2 為名字的軟鏈接,指向全局安裝下來的 vm2 包下面的 "./bin/index.js"。這時(shí)你在命令行執(zhí)行 vm2 則會(huì)調(diào)用鏈接到的這個(gè) js 文件。
main
一個(gè)常用的npm包
{
??"main":?"lib/index.js",
}
main 屬性指定程序的主入口文件,其他項(xiàng)目在引用這個(gè) npm 包時(shí),實(shí)際上引入的是 lib/index 中暴露出去的模塊。
npm script(本文重點(diǎn))
npm script 工作中應(yīng)用到的一個(gè)場景,決定看一下原理。
什么是 npm script 腳本?
在生成的 package.json 文件中,有一個(gè) scripts 對(duì)象,在這個(gè)對(duì)象中,npm 允許使用 scripts 字段定義腳本命令。
"scripts":?{
????"test":?"test.js"
????"build":?"tsc",
??},
scripts 對(duì)象中每一個(gè)屬性,對(duì)應(yīng)一段腳本。比如,test 命令對(duì)應(yīng)的腳本是 node test.js。
命令行下使用 npm run 命令,就可以執(zhí)行這段腳本。
查看當(dāng)前項(xiàng)目的所有 npm 腳本命令,可以使用不帶任何參數(shù)的npm run命令。
原理
我們每次在運(yùn)行 scripts 中的一個(gè)屬性時(shí)候(npm run),**實(shí)際系統(tǒng)都會(huì)自動(dòng)新建一個(gè)shell(一般是Bash),在這個(gè)shell里面執(zhí)行指定的腳本命令。因此 凡是能在 shell 中允許的腳本,都可以寫在npm scripts中。
特別的點(diǎn),
npm run 新建的 shell,會(huì)在當(dāng)前目錄的node_modules/.bin子目錄加入到 PATH 變量,執(zhí)行結(jié)束后,再將 PATH 變量恢復(fù)原樣。也就是說,當(dāng)前項(xiàng)目目錄node——modules/.bin子目錄中所有的腳本,都可以直接用腳本名稱調(diào)用,不需要增加路徑.(簡單總結(jié):通過 npm 啟動(dòng)的腳本,會(huì)默認(rèn)把node_modules/.bin加到 PATH 環(huán)境變量中。)
例子
當(dāng)前項(xiàng)目的依賴?yán)锩嬗?Mocha,只要直接寫 mocha test 就可以了。
"test":?"mocha?test"
而不用寫成下面這樣。
"test":?"./node_modules/.bin/mocha?test"
然后我們就可以直接執(zhí)行 npm run test 了。npm 腳本的退出碼,也遵守 Shell 腳本規(guī)則。如果退出碼不是0,npm 就認(rèn)為這個(gè)腳本執(zhí)行失敗。
這里有的小伙伴可能會(huì)有疑問,node_modules目錄下的.bin文件是哪里來的?我之前也有這樣的疑問,打開了一個(gè) .bin/tsc,里面的內(nèi)容是這樣的
#!/usr/bin/env?node
require('../lib/tsc.js')
npm install 安裝的某個(gè)模塊,如果模塊在 package.json 中配置了 bin 屬性,在安裝時(shí)候會(huì)自動(dòng)軟鏈接到 node_modules/.bin 中,舉個(gè)例子:如 mocha 源碼 配置了:
{
????"name":"mocha",
????"bin":{
????????"mocha":"./bin/mocha"
????}
}
腳本默認(rèn)值
正常情況下,npm 腳本是用戶自己定義。但是 npm 本身對(duì)兩個(gè)腳本提供了默認(rèn)值,這兩個(gè)腳本不用在 script 屬性中定義,可以直接使用
"start":?"node?server.js"
"install":?"node-gyp?rebuild"
npm run start的默認(rèn)值是node server.js,前提是根目錄下有server.js這個(gè)腳本npm run install的默認(rèn)值是node-gyp rebuild,前提是根目錄下有binding.gyp文件
擴(kuò)展小知識(shí),本文不重點(diǎn)說,
node-gyp是什么,binding.gyp文件是什么?GYP 是一種構(gòu)建自動(dòng)化工具。
node-gyp: node下的gyp。npm 為了方便直接源碼分發(fā),用戶裝的時(shí)候需要自己進(jìn)下編譯,我們?cè)陂_發(fā) node 程序中需要調(diào)用一些其他語言編寫的工具甚至 dll,這時(shí)候需要先編譯下其他語言,否則會(huì)出現(xiàn)跨平臺(tái)的問題。node-gyp是用來編譯原生C++模塊的,也可以編寫自己寫的C++文件,node-gyp在較新的Node版本中都是自帶的,而且是最先版本。gyp 文件:當(dāng) Node.js項(xiàng)目中有需要和C++交互的需求時(shí),項(xiàng)目的根目需要?jiǎng)?chuàng)建binging.gyp文件,每個(gè).gyp文件都描述了如何去構(gòu)建項(xiàng)目,每個(gè).gyp文件都描述了如何去構(gòu)建項(xiàng)目,gyp文件的語法是Python數(shù)據(jù)格式(Json格式),配置中數(shù)據(jù)是鍵-值對(duì)的形式。
看一段簡單的 .gyp 文件,應(yīng)該好理解一些。
{
????"targets":?[
????????{
????????????"target_name":?"nodecat",
????????????"sources":?[
????????????????"src/nodecat.cc",
????????????],
????????????"include_dirs":?[
????????????????"include"
????????????],
????????????"libraries":?[
????????????????"-lcatclient"
????????????]
????????}
????]
}
想了解更多詳細(xì)的可以看下面的文檔。
binging.gyp 參數(shù)說明書/文檔/指南(國外的一篇文檔抄錄,棒!)binging.gyp 參數(shù)說明書/文檔/指南
關(guān)于 node-gyp 和 binding.gyp 后面會(huì)單獨(dú)寫一篇文章,這里先簡單介紹,小伙伴們了解下。
鉤子(生命周期)
好多語言或者框架我們學(xué)的時(shí)候都會(huì)考慮到生命周期,其實(shí) package.json 中的 script 也是有生命周期的。npm 腳本有兩個(gè)鉤子,pre 和 post,當(dāng)我們執(zhí)行start腳本時(shí)候,start 的鉤子就是 prestart 和 poststart。
當(dāng)我們執(zhí)行 npm run start 的時(shí)候,npm 會(huì)自動(dòng)按照下面的順序執(zhí)行
npm?run?prestart?&&?npm?run?start?&&?npm?run?poststart
那這個(gè)鉤子有什么用呢,在實(shí)際開發(fā)中,我們可以做一些準(zhǔn)備或者清理工作,下面是個(gè)例子(引用的阮一峰老師文章中的例子)
"clean":?"rimraf?./dist?&&?mkdir?dist",
"prebuild":?"npm?run?clean",
"build":?"cross-env?NODE_ENV=production?webpack"
鉤子好用,但是不可亂用,舉個(gè)開發(fā)過程中遇到的坑,有一次想設(shè)置運(yùn)行時(shí)的環(huán)境變量,當(dāng)時(shí)想優(yōu)雅一點(diǎn),就在
prestart里面設(shè)置了一個(gè)環(huán)境變量,但是在項(xiàng)目start的時(shí)候,無法拿到設(shè)置的環(huán)境變量,因?yàn)?script的屬性運(yùn)行的時(shí)候都會(huì)新啟動(dòng)一個(gè)shell,所以在prestart中設(shè)置的環(huán)境變量只對(duì)應(yīng)了那個(gè)shell的運(yùn)行時(shí)。
env 環(huán)境變量
我們?cè)趫?zhí)行 npm run 腳本時(shí)候, npm 會(huì)設(shè)置一些特殊的env環(huán)境變量。其中package.json中的所有字段,都會(huì)被設(shè)置為以npm_package_開頭的環(huán)境變量。看個(gè)簡單的例子
{
??"name":?"npm-demo",
??"version":?"1.0.0",
??"script":?{
????"build":?"webpack?--mode=production"
??},
??"files":?["src"]
}
可以得到 npm_package_name、npm_package_version、npm_package_script_build、npm_package_files_0等變量。注意上面 package.json 中對(duì)象和數(shù)組中每個(gè)字段都會(huì)有對(duì)應(yīng)的環(huán)境變量。
同時(shí),npm 相關(guān)的所有配置也會(huì)被設(shè)置為以npm_config_開頭的環(huán)境變量。此外,還會(huì)設(shè)置一個(gè)比較特殊的環(huán)境變量npm_lifecycle_event,表示正在運(yùn)行的腳本名稱。比如執(zhí)行npm run serve 的時(shí)候,process.env.npm_lifecycle_event值為serve,通過判斷這個(gè)變量,可以將一個(gè)腳本使用在不同的npm scripts中。這里還要提一下上面說的鉤子,npm_lifecycle_event可以和鉤子配合使用,利用這個(gè)變量,在同一個(gè)腳本文件里面,為不同的 npm scripts 命令編寫代碼。請(qǐng)看下面的例子。
const?TARGET?=?process.env.npm_lifecycle_event;
if?(TARGET?===?'service')?{
??console.log(`Running?the?service?task!`);
}
if?(TARGET?===?'preservice')?{
??console.log(`Running?the?preservice?task!`);
}
if?(TARGET?===?'postservice')?{
??console.log(`Running?the?postservice?task!`);
}
強(qiáng)調(diào):這些環(huán)境變量只能在
npm run的腳本執(zhí)行環(huán)境內(nèi)拿到,正常執(zhí)行的 node 腳本是獲取不到的。所以,不能直接通過env $npm_package_name的形式訪問,但可以在 scripts 中定義腳本"scripts": {"bundle": "echo $npm_package_name"}來訪問。
環(huán)境變量常用小技巧
env 命令可以列出所有環(huán)境變量
npm?run?env
在shell腳本中輸出環(huán)境變量
echo?PATH
在 shell 腳本設(shè)置環(huán)境變量
echo?PATH?=?/usr/local/lib
有的時(shí)候我們需要設(shè)置的環(huán)境變量是相對(duì)項(xiàng)目的再補(bǔ)充一個(gè)shell腳本中設(shè)置環(huán)境變量時(shí)候如何拼接相對(duì)路徑
echo?PATH?=?${pwd}/lib/include??//使用${},也可以直接使用雙引號(hào)
腳本傳入?yún)?shù)
說到腳本傳入?yún)?shù),需要再次提到前面說的 pacakge.json 中的 bin 字段,bin 字段指定了各個(gè)內(nèi)部命令對(duì)應(yīng)的可執(zhí)行文件的位置。前面已經(jīng)說了 bin 文件的產(chǎn)生,有了 bin 字段,在安裝這個(gè)模塊的時(shí)候,node_modules 下面的 .bin/文件夾 下會(huì)有對(duì)應(yīng)模塊的文件,和模塊中的文件相同,然后我們就可以通過調(diào)用這個(gè)文件腳本中的方法傳入?yún)?shù)了。
在我的 node_module 中找到一個(gè)簡單 .bin/文件 下的腳本,大家感受一下。
#!/usr/bin/env?node
'use?strict';
var?pkg?=?require('./package.json');
var?osName?=?require('./');
var?argv?=?process.argv;
function?help()?{
?console.log([
??'',
??'??'?+?pkg.description,
??'',
??'??Example',
??'????os-name',
??'????OS?X?Mavericks'
?].join('\n'));
}
if?(argv.indexOf('--help')?!==?-1)?{
?help();
?return;
}
if?(argv.indexOf('--version')?!==?-1)?{
?console.log(pkg.version);
?return;
}
console.log(osName());
node 處理 scripts 中的參數(shù),除了屬性后面的第一個(gè)命令,以空格分割的任何字符串(除特別shell語法)都是參數(shù),并且都能通過 process.argv 屬性訪問。
process.argv屬性返回一個(gè)數(shù)組,數(shù)組包含了啟動(dòng)node進(jìn)程時(shí)的命令行參數(shù)。第一個(gè)元素為啟動(dòng)node進(jìn)程的可執(zhí)行文件的絕對(duì)路徑名process.execPath,第二個(gè)元素為當(dāng)前執(zhí)行的jacascript文件路徑。剩余的元素為其他命令行參數(shù)。
如下 script 例子
"scripts":{
??"serve":?"vue-cli-service?serve?--mode=dev?--mobile?-config?build/example.js"
}
當(dāng)我們執(zhí)行 npm run server 命令的時(shí)候,process.argv 的具體內(nèi)容為:
[?'/usr/local/Cellar/node/12.14.1/bin/node',
??'/Users/mac/Vue-projects/hao-cli/node_modules/.bin/vue-cli-service',
??'serve',
??'--mode=dev',
??'--mobile',
??'-config',
??'build/example.js']
再列舉幾個(gè)傳參可能有的方式
npm?run?serve?--params??//?參數(shù)params將轉(zhuǎn)化成process.env.npm_config_params?=?true
npm?run?serve?--params=123?//?參數(shù)params將轉(zhuǎn)化成process.env.npm_config_params?=?123
npm?run?serve?-params??//?等同于--params參數(shù)
npm?run?serve?--?--params??//?將--params參數(shù)添加到process.env.argv數(shù)組中
npm?run?serve?params??//?將params參數(shù)添加到process.env.argv數(shù)組中
npm?run?serve?--?params??//?將params參數(shù)添加到process.env.argv數(shù)組中
對(duì)比下 npm install koa2 --save 是不是知道了bin腳本中接收到的 process.env.npm_config_save = true; 我想是這樣的,有興趣的小伙伴去看源碼驗(yàn)證下。
執(zhí)行順序
npm 腳本執(zhí)行多任務(wù)分為兩種情況
并行任務(wù)(同時(shí)的平行執(zhí)行),使用&符號(hào)
$?npm?run?script1.js?&?npm?run?script2.js
串行任務(wù)(前一個(gè)任務(wù)成功,才執(zhí)行下一個(gè)任務(wù)),使用 && 符號(hào)
$?npm?run?script1.js?&&?npm?run?script2.js
任意腳本
我們配置的腳本命令,如 "start": "node test.js",node test.js 會(huì)當(dāng)做一行代碼傳遞給系統(tǒng)的 shell 去解釋執(zhí)行。實(shí)際使用的 shell 可能會(huì)根據(jù)系統(tǒng)平臺(tái)而不同,類 UNIX 系統(tǒng)里,如 macOS 或 linux 中指代的是 /bin/sh, 在 windows 中使用的是 cmd.exe。原理我們也看了,因?yàn)榻唤o shell 去解釋執(zhí)行的,說明配置的腳本可以是任意能夠在 shell 中運(yùn)行的命令,而不僅僅是 node 腳本或者 js 代碼。如果你的系統(tǒng)里安裝了 python(或者說系統(tǒng)變量 PATH里能找到 python 命令),你也可以將 scripts 配置為 "myscript": "python xxx.py"
npm 配置
npm 的配置操作可以幫助我們預(yù)先設(shè)定好npm對(duì)項(xiàng)目的行為動(dòng)作,也可以讓我們預(yù)先定義好一些配置項(xiàng)以供項(xiàng)目中使用。所以了解npm的配置機(jī)制也是很有必要。
npm config
npm cli 提供了 npm config 命令進(jìn)行 npm 相關(guān)配置,通過 npm config ls -l 可查看 npm 的所有配置,包括默認(rèn)配置。npm 文檔頁為每個(gè)配置項(xiàng)提供了詳細(xì)的說明 https://docs.npmjs.com/misc/config .修改配置的命令為 npm config set
proxy, https-proxy: 指定 npm 使用的代理registry指定npm下載安裝包時(shí)的源,默認(rèn)為https://registry.npmjs.org/可以指定為私有Registry源package-lock指定是否默認(rèn)生成package-lock文件,建議保持默認(rèn) truesave true/false指定是否在npm install后保存包為dependencies,npm 5起默認(rèn)為true
刪除指定的配置項(xiàng)命令為 npm config delete .
這里最常見的一個(gè)操作是 npm 太慢,設(shè)置淘寶鏡像
npm config set registry https://registry.npm.taobao.org
恢復(fù)使用之前的 npm
npm config set registry https://registry.npmjs.org
env 環(huán)境變量
如果env環(huán)境變量中存在以npm_config_為前綴的環(huán)境變量,則會(huì)被識(shí)別為npm的配置屬性。比如在env環(huán)境變量中設(shè)置npm_config_package_lock變量:
export?npm_config_package_lock=false?//修改的是內(nèi)存中的變量,只對(duì)當(dāng)前終端有效
這時(shí)候執(zhí)行npm install,npm會(huì)從環(huán)境變量中讀取到這個(gè)配置項(xiàng),從而不會(huì)生成package-lock.json文件。
查看某個(gè)環(huán)境變量:echo $NODE_ENV刪除某個(gè)環(huán)境變量:unset NODE_ENV
npmrc 文件
除了使用 CLI 的 npm config 命令顯示更改 npm 配置,還可以通過 npmrc 文件直接修改配置。
這樣的 npmrc 文件優(yōu)先級(jí)由高到低包括:
工程內(nèi)配置文件: /path/to/my/project/.npmrc用戶級(jí)配置文件: ~/.npmrc全局配置文件: $PREFIX/etc/npmrc(即npm config get globalconfig 輸出的路徑)npm內(nèi)置配置文件: /path/to/npm/npmrc
很多時(shí)候我們?cè)诠緝?nèi)網(wǎng)需要通過代理才能訪問npm源,通過這個(gè)機(jī)制,我們可以方便地在工程跟目錄創(chuàng)建一個(gè) .npmrc 文件來共享需要在團(tuán)隊(duì)間共享的 npm 運(yùn)行相關(guān)配置。比如如果我們?cè)诠緝?nèi)網(wǎng)環(huán)境下需通過代理才可訪問 registry.npmjs.org 源,或需訪問內(nèi)網(wǎng)的 registry, 就可以在工作項(xiàng)目下新增 .npmrc 文件并提交代碼庫。
proxy?=?http://proxy.example.com/
https-proxy?=?http://proxy.example.com/
registry?=?http://registry.example.com/
因?yàn)轫?xiàng)目級(jí) .npmrc 文件的作用域只在本項(xiàng)目下,所以在非本目錄下,這些配置并不生效。對(duì)于使用筆記本工作的開發(fā)者,可以很好地隔離公司的工作項(xiàng)目、在家學(xué)習(xí)研究項(xiàng)目兩種不同的環(huán)境。
將這個(gè)功能與 ~/.npm-init.js 配置相結(jié)合,可以將特定配置的 .npmrc 跟 .gitignore, README 之類文件一起做到 npm init 腳手架中,進(jìn)一步減少手動(dòng)配置。
npm 包發(fā)布
規(guī)范的 npm 模塊目錄
一個(gè) node.js 模塊是基于 CommonJS 模塊化規(guī)范實(shí)現(xiàn)的,嚴(yán)格按照 CommonJS 規(guī)范,模塊目錄下除了必須包含包描述文件 package.json 以外,還需要包含以下目錄:
bin:存放可執(zhí)行二進(jìn)制文件的目錄 lib:存放js代碼的目錄 doc:存放文檔的目錄 test:存放單元測試用例代碼的目錄
如何寫好一個(gè)模塊的 README 文件
這里不單獨(dú)寫,推薦一篇不錯(cuò)的討論
https://www.zhihu.com/question/29100816
如何發(fā)布自己的 npm 包
先去 npm 注冊(cè)個(gè)賬號(hào),然后在命令行使用
npm?adduser?#根據(jù)提示輸入用戶名密碼即可
使用命令發(fā)布你的包
在推送之前,可以通過配置一個(gè)
.npmignore文件來排除一些文件, 防止大量的垃圾文件推送到npm, 規(guī)則上和你用的.gitignore是一樣的。.gitignore文件也可以充當(dāng).npmignore文件
npm?publish
發(fā)布成功之后,你就可以像下載安裝其他包一樣使用你自己的開發(fā)工具了
npm?install?koalanpmstudy
關(guān)于 npm 包的更新
更新 npm 包也是使用 npm publish 命令發(fā)布,不過必須更改 npm 包的版本號(hào),即 package.json 的 version 字段,否則會(huì)報(bào)錯(cuò),同時(shí)我們應(yīng)該遵 Semver(語義化版本號(hào)) 規(guī)范,npm 提供了 npm version 給我們升級(jí)版本
#?升級(jí)補(bǔ)丁版本號(hào)
$?npm?version?patch
#?升級(jí)小版本號(hào)
$?npm?version?minor
#?升級(jí)大版本號(hào)
$?npm?version?major
本地開發(fā)的 npm 包如何調(diào)試
在本地開發(fā)的模塊包的時(shí)候,可以使用 npm link 調(diào)試,將模塊鏈接到對(duì)應(yīng)的運(yùn)行項(xiàng)目中去,方便地對(duì)模塊進(jìn)行調(diào)試和測試。具體使用步驟如下
假如我的項(xiàng)目是 koalaNpmStudy,假如我的 npm 模塊包名稱是npm-ikoala進(jìn)入到 模塊包 npm-ikoala目錄中,執(zhí)行npm link在自己的項(xiàng)目 koalaNpmStudy中創(chuàng)建連接執(zhí)行npm link npm-ikoala在自己項(xiàng)目的 node_module中會(huì)看到鏈接過來的模塊包,然后就可以像使用其他的模塊包一樣使用它了。調(diào)試結(jié)束后可以使用 npm unlink取消關(guān)聯(lián)
npm link主要做了兩件事:
為目標(biāo) npm模塊創(chuàng)建軟鏈接,將其鏈接到全局node模塊安裝路徑/usr/local/lib/node_modules/。為目標(biāo) npm模塊的可執(zhí)行bin文件創(chuàng)建軟鏈接,將其鏈接到全局node命令安裝路徑/usr/local/bin/。
總結(jié)
本文對(duì) npm 相關(guān)的內(nèi)容進(jìn)行了一個(gè)梳理,npm install 原理以及和 npm 與yarn 的區(qū)別沒有講,會(huì)在下一篇文章進(jìn)行講解。希望本文看完對(duì)小伙伴們有幫助。
?? 看完三件事
點(diǎn)個(gè)「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點(diǎn)在看,都是耍流氓 -_-)
關(guān)注我的官網(wǎng)?https://muyiy.cn,讓我們成為長期關(guān)系
關(guān)注公眾號(hào)「高級(jí)前端進(jìn)階」,公眾號(hào)后臺(tái)回復(fù)「面試題」 送你高級(jí)前端面試題,回復(fù)「加群」加入面試互助交流群
