什么是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 脚本编程有一个入门的了解,再也不会感觉到陌生了。如果还有哪里不清楚的欢迎留言,我们一起探讨学习。

参考文献

npm scripts 脚本基础指南的更多相关文章

  1. 5.npm scripts 使用指南

    简单介绍 scripts里面的 "start": "node app" npm run start 相当于 node app { "name" ...

  2. npm scripts 使用指南

    转载自:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html Node 开发离不开 npm,而脚本功能是 npm 最强大.最常用的功能之一. ...

  3. 二、npm scripts

    一.执行原理 安装npm 包,会将其package.json bin 字段添加到node_modules bin 里面,创建对应的.cmd文件,因此: 例如: "scripts": ...

  4. Vue.js源码解析-从scripts脚本看vue构建

    目录 1. scripts 脚本构建 1.1 dev 开发环境构建过程 1.1.1 配置文件代码 1.1.2 如何进行代码调试? 1.2 build 生产环境构建过程 1.2.1 scripts/bu ...

  5. npm Scripts使用教程【译】

    Why npm Scripts? 原文发表于 2016.2.12,原文地址: https://css-tricks.com/why-npm-scripts/ 以下是访客Damon Bauer发布的一篇 ...

  6. windows下npm scripts不能执行的问题

    最近在学webpack为了方便把运行脚本写入package.json文件中,如下: "scripts": { "start": "webpack-de ...

  7. 我为何放弃Gulp与Grunt,转投npm scripts(上)

    本文来源于我在InfoQ中文站翻译的文章.原文地址是:http://www.infoq.com/cn/news/2016/02/gulp-grunt-npm-scripts-part1 Cory Ho ...

  8. Shell脚本学习指南笔记

    Shell脚本学习指南 作者:Danbo 2015-8-3 脚本编程语言与编译型语言的差异 许多中型.大型的程序都是用编译型语言写的,例如:C.C+.Java等.这类程序只要从源代码(Source C ...

  9. 【在 Nervos CKB 上做开发】Nervos CKB脚本编程简介[2]:脚本基础

    CKB脚本编程简介[2]:脚本基础 原文作者:Xuejie 原文链接:Introduction to CKB Script Programming 2: Script 本文译者:Shooter,Jas ...

随机推荐

  1. 「CodeForces - 717E」Paint it really, really dark gray (dfs)

    BUPT 2017 summer training (for 16) #1H 题意 每个节点是黑色or白色,经过一个节点就会改变它的颜色,一开始在1节点.求一条路径使得所有点变成黑色. 题解 dfs时 ...

  2. Leetcode 80.删除排序数组中的重复项 II By Python

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 ...

  3. [SPOJ913]QTREE2 - Query on a tree II【倍增LCA】

    题目描述 [传送门] 题目大意 给一棵树,有两种操作: 求(u,v)路径的距离. 求以u为起点,v为终点的第k的节点. 分析 比较简单的倍增LCA模板题. 首先对于第一问,我们只需要预处理出根节点到各 ...

  4. 【转】linux清屏的几种方法

    在windows的DOS操作界面里面,清屏的命令是cls,那么在linux 里面的清屏命令是什么呢?下面笔者分享几种在linux下用过的清屏方法. 1.clear命令.这个命令将会刷新屏幕,本质上只是 ...

  5. CSS居中的几种方式总结

    1.水平居中的 margin:0 auto; 这个是用于子元素上的,前提是不受float影响 <style type="text/css"> .box{ width: ...

  6. 洛谷 P5020 【货币系统】

    谁说这一定要排序的,这就是个装满背包嘛 \({f[i]}\) 表示 \(i\) 面值最多能被几张钱表示 则若其不能被表示 \(f[i]=-inf\) 能表示且只有它自己则 \(f[i]=1\) 初始化 ...

  7. GNOME下让QT应用使用adwaita主题统一外观

    效果展示 使用前 使用后 步骤 Arch Linux下使用AUR安装 sudo yaourt adwaita-qt4 adwaita-qt5 sudo pacman -S qtconfig-qt4 q ...

  8. A1064. Complete Binary Search Tree

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  9. 【CH6803】导弹防御塔

    题目大意:给定 N 座塔,M 个怪物,每座塔一次可以发射一枚导弹,发射导弹有发射时间和冷却时间,每座塔和每只怪物有自己的二维坐标,所有导弹有一个共同的速度,求至少需要多长时间才能将所有怪物消灭. 题解 ...

  10. C++ 容器操作

    typedef struct point { int x; int y; }Point; 在声明变量的时候就可以:Point p1; 如果没有typedef, 如: struct point { in ...