本文翻譯自npm官方script文檔javascript
npm 支持運行package.json裏「scripts」屬性中的腳本,包括:java
prepublish
:在npm publish
命令以前運行(也會在不帶參數的npm install
命令前運行,詳情在下段描述)node
prepare
: 在兩種狀況前運行,一是npm publish
命令前,二是不帶參數的npm install
命令;它會在prepublish
以後、prepublishOnly
以前執行git
prepublishOnly
: 在npm publish
命令前執行github
publish,postpublish
: 在npm publish
命令後執行npm
preinstall
: 在npm install
命令前執行json
install,postinstall
: 在npm install
命令後執行curl
preuninstall,uninstall
: 在npm uninstall
命令前執行工具
postuninstall
: 在npm uninstall
命令後執行post
preversion
:在改變包的version前執行
version
: 在改變包的version後,但提交以前執行
postversion
: 在提交version變動後執行
pretest, test, posttest
: 伴隨npm test
命令
prestop, stop, poststop
: 伴隨npm stop
命令
restart, start, poststart
: 伴隨 npm start
命令
pre restart, restart, poststart
: 伴隨 npm restart
命令。提示:假如scripts裏沒有寫restart命令,npm默認會運行start、stop
preshrinkwrap, shrinkwrap, postshrinkwrap
: 伴隨 npm shrinkwrap
命令(用於固定依賴包版本)
另外,全部的script均可以用 npm run-script <stage>
命令執行, pre 和 post 會自動匹配對應的script(例如 premyscript,my script, postmyscript
),依賴包中的script能夠用npm explore <pkg> -- npm run <stage>
來執行
從npm@1.1.71開始,npm CLI 會在npm publish
和npm install
以前執行prepubish
腳本,由於這作法便於準備package環境(幾種用法如本段下面描述)。但事實證實這讓人很是困惑。因此在npm@4.0.0後,新增來一種事件prepare
來替代上述功能。另一種新事件prepublishOnly
做爲替代策略,讓用戶避免以往npm版本的混亂行爲。prepublishOnly
只在npm publish
前執行(例如,publish前最後執行一次測試,以確保無誤)
重要提示:在npm5中, prepublish
只在npm publish
前執行,即取代prepublishOnly
,因此npm6即之後的版本會放棄prepublishOnly
。到時就忘了這些矬事吧。
https://github.com/npm/npm/issues/10074 ,這裏對此變動有過漫長的爭論可做參考。
若是你須要在使用package以前執行某些操做,而不依賴於目標系統的操做系統或目錄結構,請使用prepublish腳本。例如如下任務:
把coffeescript源碼編譯成JS
壓縮js源碼
獲取你的package所需的遠程資源
在publish時作這些事情的好處是,它們能夠在同一處完成,從而下降複雜性和差別性。另外,這意味着:
你能夠依賴於coffee-script做爲devDependency,但你的用戶不須要安裝它。
你不須要在包中包含min版本,以節省空間
你的用戶的電腦上沒必要具備curl或wget或其餘系統工具
npm 預設了幾個script內容:
"start": "node server.js"
若是你的package根目錄中有server.js, npm會默認以之做爲start命令執行。
"install": "node-gyp rebuild"
若是你的package根目錄下中有binding.gyp而你又沒定義 install或preinstall腳本,npm會默認以npm-gyp編譯。
若是使用root權限調用npm,那麼它會將uid更改成用戶配置指定的uid,默認爲nobody。設置unsafe-perm以使用root權限運行腳本。
npm 腳本運行在 npm的設置和進程的當前狀態 的環境中。(不知道怎麼翻)
Package scripts run in an environment where many pieces of information are made available regarding the setup of npm and the current state of the process.
若是你依賴的模塊(如測試模塊)定義了可執行腳本,那麼這些可執行文件將被添加到PATH中執行。因此,若是你的package.json有這樣的依賴:
{ "name" : "foo", "dependencies" : { "bar" : "0.1.x" }, "scripts": { "start" : "bar ./test" } }
那麼在你npm install
時,bar會導進node_modules/.bin
目錄中,你能夠運行npm start
執行 bar腳本。
package.json的屬性名會拼接上npm_package_
前綴。例如若是你的package.json文件中有{「name」:「foo」,「version」:「1.2.5」})
,那麼你的腳本中npm_package_name
會是foo
,而npm_package_version
會是1.2.5
使用npm_config_
前綴將配置參數放在環境中。例如你能夠經過檢查npm_config_root
環境變量來查看目前生效的root配置。
特殊:package.json中的config對象
若是npm config中存在<name> [@ <version>]:<key>的配置參數,則package.json裏config對應的key將在環境中被覆蓋。例如,若是package.json中:
{ "name" : "foo", "config" : { "port" : "8080" }, "scripts" : { "start" : "node server.js" } }
而server.js中這麼寫:
http.createServer(...).listen(process.env.npm_package_config_port)
那麼用戶能夠這樣覆寫port變量:
npm config set foo:port 80
最後,npm_lifecycle_event
環境變量表明當前執行循環的哪一個階段。因此,你可使用單個腳本用於根據當前正在發生的事件切換的進程的不一樣部分。
對象按照層級如下劃線鏈接,若是您的package.json中有
{「scripts」:{「install」:「foo.js」}}
則能夠在腳本中看到:
process.env.npm_package_scripts_install === "foo.js"
假如你的package.json有以下設置:
{ "scripts" : { "install" : "scripts/install.js", "postinstall" : "scripts/install.js", "uninstall" : "scripts/uninstall.js" } }
那麼在生命週期的install
和postinstall
階段將調用scripts/install.js
,在uninstall
時將會調用scripts/uninstall.js
。
因爲scripts/install.js
在兩個不一樣的階段都有運行,所以在這種狀況下,查看npm_lifecycle_event
變量是聰明的作法。
若是你想要運行make命令也沒問題,這樣寫:
{ "scripts" : { "preinstall" : "./configure", "install" : "make && make install", "test" : "make test" } }
npm腳本是經過將該行做爲腳本參數傳給sh來運行的。
若是腳本不是以退出碼0退出,則會停止該進程。
請注意,這些腳本文件沒必要是nodejs甚至是javascript程序。他們只須要一些可執行文件。
若是要爲全部package在某生命週期事件中運行某腳本,則可使用鉤子腳本。
在node_modules/.hooks/{eventname}
中放置一個可執行文件,全部裝在根目錄下的package在運行到該生命週期節點時都會執行。
Hook腳本的運行方式與package.json裏的腳本徹底相同。也就是說,它們與上述env在一個單獨的子進程中。
不要以0之外的錯誤碼退出,除非你真的想這樣作。由於這將致使npm操做失敗(install
腳本除外),並可能會回滾。若是這個錯誤可有可無或只會阻斷一些小功能,那麼最好只是輸出一個警告,讓線程成功退出。
儘可能不要使用npm腳原本作npm自己就能夠作的事情。通讀package.json文件,你能夠學到全部經過簡單、合適的配置來具體描述你的package。這一般更健壯和通用。
經過檢查env
來決定把東西裝在哪。例如,若是npm_config_binroot
環境變量設置爲/home/user/bin
,那麼不要嘗試將可執行文件安裝到/usr/local/bin
中。用戶可能由於某種緣由設置了這種方式。
不要在腳本命令里加sudo
前綴。若是因爲某些緣由須要root權限,不然會報錯;那麼用戶應該考慮以sudo運行npm命令。
不要使用install
腳本。使用.gyp
文件進行編譯,其餘狀況則使用prepublish
。你最好永遠不要自定義preinstall
或install
腳本。若是你要這樣作,請優先考慮是否有其餘辦法。install
或preinstall
腳本的惟一正確使用場景是用做設置那些編譯的目標目錄。