npm scripts 腳本基礎指南


什么是npm腳本?

npm 允許在package.json文件里面,使用scripts字段定義腳本命令。

初始化package.json -> npm init -> 經歷一系列的問答即可

{
  // ...
  "scripts": {
    "build": "node start.js"
  }
}

此時我們執行 npm run build 就等於執行 node start.js

【npm腳本的優勢】

  • 項目的相關腳本都集中在一個地方
  • 可以利用 npm 提供的很多輔助功能

代碼示例:

執行命令

mkdir npmscript
cd npmscript
npm init
...一路回車

start.js
一個簡單的web服務器代碼

//引入http模塊
var http = require("http");
//設置主機名
var hostName = '127.0.0.1';
//設置端口
var port = 8088;
//創建服務
var server = http.createServer(function(req,res){
    res.setHeader('Content-Type','text/plain');
    res.end("hello nodejs");

});
server.listen(port,hostName,function(){
    console.log(`服務器運行在http://${hostName}:${port}`);
});

執行剛設置好的命令 npm run build

npm scripts 原理

npm 腳本的原理非常簡單。每當執行npm run,就會自動新建一個 Shell,在這個 Shell 里面執行指定的腳本命令。因此,只要是 Shell(一般是 Bash)可以運行的命令,就可以寫在 npm 腳本里面。
比較特別的是,npm run新建的這個 Shell,會將當前目錄的node_modules/.bin子目錄加入PATH變量,執行結束后,再將PATH變量恢復原樣。
這意味着,當前目錄的node_modules/.bin子目錄里面的所有腳本,都可以直接用腳本名調用,而不必加上路徑。比如,當前項目的依賴里面有 Mocha,只要直接寫mocha test就可以了。

"test": "mocha test"

而不同寫成下面這樣

"test": "./node_modules/.bin/mocha test"

由於 npm 腳本的唯一要求就是可以在 Shell 執行,因此它不一定是 Node 腳本,任何可執行文件都可以寫在里面。

npm 腳本的退出碼,也遵守 Shell 腳本規則。如果退出碼不是0,npm 就認為這個腳本執行失敗。

通配符

由於 npm 腳本就是 Shell 腳本,因此可以使用shell通配符

"lint": "jshint *.js" // * 表示所有

傳遞參數和獲取參數

【方法一】
向npm 腳本傳入參數,要使用 -- 表明。

"scripts": {
    "build": "node start.js -- port=8090" // 通過 -- port=8090 傳入參數
  }

在我們的start.js文件中獲取

// 打印process.argv對象看下
console.log(process.argv);

看下輸出什么?

可以看到數組中有port的相關信息,我們在通過數組方法就可以取出相應的值。

【方法二】
package.json中添加config

"config": {
    "port": "8099"
  }

然后在start.js中打印 process.env.npm_package_config_port 的信息看看

同樣也可以獲取到相應的信息

執行順序

並行執行: &

npm run script1.js & npm run script2.js

繼發執行:&&

npm run script1.js && npm run script2.js

默認值

一般來說,npm 腳本由用戶提供。但是,npm 對兩個腳本提供了默認值。也就是說,這兩個腳本不用定義,就可以直接使用

"start": "node server.js",
"install": "node-gyp rebuild"

上面代碼中,npm run start的默認值是node server.js,前提是項目根目錄下有server.js這個腳本;npm run install的默認值是node-gyp rebuild,前提是項目根目錄下有binding.gyp文件。

鈎子

npm腳本有pre和post兩個鈎子。

{
  "name": "npmscripts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "prebuild":"echo I run before the build script",
    "build": "node start.js -- port=8090",
    "postbuild":"echo I run after the build script"
  },
  "author": "",
  "license": "ISC"
}

start.js 建一個空文件即可

用戶執行 npm run build的時候,會自動按照下面的順序執行。

npm run prebuild && npm run build && npm run postbuild 

因此可以在pre和post鈎子上完成一些准備工作和清理工作;

再執行下npm run build 可以看看結果

【默認鈎子】

prepublish,postpublish
preinstall,postinstall
preuninstall,postuninstall
preversion,postversion
pretest,posttest
prestop,poststop
prestart,poststart
prerestart,postrestart

【自定義命令的鈎子】

自定義的腳本命令也可以加上pre和post鈎子。比如,myscript這個腳本命令,也有premyscript和postmyscript鈎子

npm 提供一個npm_lifecycle_event變量,返回當前正在運行的腳本名稱,比如pretest、test、posttest等等。所以,可以利用這個變量,在同一個腳本文件里面,為不同的npm scripts命令編寫代碼。

package.json

{
  "name": "npmscripts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "pretest": "node start.js",
    "test": "node start.js",
    "posttest": "node start.js"
  },
  "author": "",
  "license": "ISC"
}

start.js

const TARGET = process.env.npm_lifecycle_event;

if (TARGET === 'test') {
  console.log(`Running the test task!`);
}

if (TARGET === 'pretest') {
  console.log(`Running the pretest task!`);
}

if (TARGET === 'posttest') {
  console.log(`Running the posttest task!`);
}

執行命令 npm run test 可以看看效果;

簡寫形式

四個常用的npm腳本有簡寫形式

npm start是npm run start
npm stop是npm run stop的簡寫
npm test是npm run test的簡寫
npm restart是npm run stop && npm run restart && npm run start的簡寫

變量

可以通過process.env 獲取到package.json中定義的內容。要加上npm_package_前綴。看下代碼
package.json

{
  "name": "npmscripts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "node start.js"
  },
  "author": "",
  "license": "ISC"
}

start.js

// 打印process.env對象看下
console.log(process.env);

看下輸出的內容部分截圖

具體我就不全部截圖了,總之可以獲取到package.json中的所有數據到

總結:通過本章的學習,讓我們對npm scripts 腳本編程有一個入門的了解,再也不會感覺到陌生了。如果還有哪里不清楚的歡迎留言,我們一起探討學習。

參考文獻


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM