前言

这个主题之前有分享过的,不过没有今天这么基础,本文由@yangfch3带来的分享,比较偏原理跟实践性。


正文从这开始~


npm 不仅可以用于 模块管理,还可以用于 执行脚本。


package.json 文件有一个 scripts 字段,可以用于指定脚本命令,供 npm 直接调用。


npm scripts详解_npm


其中 commit.sh 文件内容为:


npm scripts详解_打包_02

接下来我们运行:

npm scripts详解_打包_03

便相当于执行 sh commit.sh 任务


npm run 会创建一个新的 shell,执行指定的命令,并将 node_modules/.bin 加入 PATH 变量。当脚本内容结束,则子 shell 关闭,回到父 shell 中。


0. npm run & npm run-script

这两命令的效果都是一样的,都能执行 package.json 文件 scripts 字段下指定的任务。


npm run 是 npm run-script 的缩写,一般都使用 前者,但是后者可以更好地反应这个命令的本质。


直接运行 npm run 或 npm run-script,不加参数会列出 scripts 属性下所有可运行的命令极其命令内容。

npm scripts详解_nodejs_04

1. 智能路径

npm run 命令会自动在环境变量 $PATH 添加 node_modules/.bin 目录,所以 scripts 字段里面调用命令时不用加上路径。


所以我们在 package.json 文件内的 scripts 字段内指定任务的时候 一般 无需指定脚本文件的路径,只需要将脚本放到 ./node_module/.bin/ 目录下即可,命令会在 这个目录 下自动寻找对应的脚本文件。而无需使用./node_modules/.bin/jshint**.js


当然你也可以更改与指定你需要运行的脚本的文件位置,如下:


npm scripts详解_打包_05

2. npm test & npm start

npm 内置了两个简写的命令,npm test 等同于执行 npm run test,npm start 等同于执行 npm run start。


这两个 test、start 都可以在 scripts 字段下自己定义。


3. 管道式命令

如果希望同时执行多个任务,可以借用 Linux 系统的 管道命令,将两个操作连在一起。


在 package.json 文件的 scripts 字段内的一个任务可以由多个子任务组成。

|:连接两个任务


npm scripts详解_npm_06

&&:任务内部引用其他任务,子任务 先后 执行


npm scripts详解_打包_07

&:任务内部引用其他任务,子任务 平行 执行

npm scripts详解_打包_08

流操作示例:


npm scripts详解_nodejs_09

上面我们在 package.json 中定义了一个叫做 build-css 的任务,他又两个任务组成;当我们使用npm run build-css 时会执行两个子任务(前提是这两个子任务的模块在本地或全局已安装,不报错)。


4. bash 脚本

写在 scripts 属性中的命令,也可以在 node_modules/.bin 目录中直接写成 bash 脚本。下面是一个 bash 脚本(命名为:build-js.sh)。


npm scripts详解_nodejs_10

我们在 package.json 内定义执行该脚本的命令:


npm scripts详解_json_11

并且需要设置脚本文件权限为可执行。


之后我们只需要运行:


npm scripts详解_npm_12

即可自动执行我们建立好的脚本!

npm 搭配脚本是十分方便的一件事情,也是我们提高效率的一大利器! 

关于 bash 脚本的书写,请看此文


5. 参数

npm run 命令还可以接参数。


package.json:在 newTxt 任务中未指定具体执行的脚本


npm scripts详解_npm_13

我们在 node_module/.bin/ 下新建一个待会要传入 newTxt 任务的脚本文件 newTxt.sh:


npm scripts详解_打包_14

然后我们运行:

npm scripts详解_字段_15

这样,newTxt.sh 便会作为参数传入我们的 newTxt 任务。


因为一个命令可以执行多个脚本:所以传入的参数并不会覆盖原来的参数,而是并行(或先后)执行。

npm scripts详解_json_16



上面命令表示,mocha 要运行所有 test 子目录的测试脚本,以及 另外一个测试脚本 anothertest.js。

  • 传入参数的格式:-- 
    在参数之前加入 -- 并用空格使命令与参数隔开

  • 其他参数: 
    npm run 本身有一个参数-s,表示关闭 npm 工具本身的输出,只输出脚本产生的结果。

npm scripts详解_nodejs_17

6. scripts 脚本命令最佳实践

1. npm-run-all

这是一个用于方便地运行多个 scripts 脚本的命令。

安装:npm install npm-run-all --save-dev


  • 继发执行

npm scripts详解_nodejs_18


  • 并行执行:--parallel

npm scripts详解_json_19

  • 混合执行:并行与继发混合

npm scripts详解_字段_20


  • 通配执行

npm scripts详解_nodejs_21

2. 常见脚本命令

  • start 脚本命令 
    一般用于项目的初始化,是接下来一切工作的依赖起始端

  • dev 脚本命令 
    规定开发阶段所要做的处理,比如监视文件变化、实时编译……

  • server 脚本命令 
    一般用于启动服务

  • test 脚本命令 
    一般用于执行测试:单元测试、*-lint……

  • prod 脚本命令 
    一般用于规定进入生产环境时需要做的处理

  • help 脚本命令 
    help 脚本命令一般用于展示帮助信息。

  • docs 脚本命令 
    docs 脚本命令一般用于生成文档。



3. pre- 和 post- 脚本命令

npm run 为每条命令提供了 pre- 和 post- 两个钩子(hook)。以 npm run test 为例,如果我们的 scripts 字段规定了 pretest 和 posttest:

npm scripts详解_npm_22

则会先执行 pretest 任务,再执行 test 任务,完成 test 任务后即执行 posttest 任务。

可以简单的将二者理解为:预执行、后执行


4. 内部变量

scripts 字段可以使用一些内部变量,主要是 package.json 的各种字段。内部变量的主要特征是 $npm_package_key。


比如,package.json 的内容是 {"name":"foo","version":"1.2.5"},那么变量 $npm_package_name 的值是foo,变量 npm_package_version 的值是 1.2.5。

npm scripts详解_字段_23

运行 npm run bundle 以后,将会生成 build/1.2.5/ 子目录。


config 字段也可以用于设置内部字段。

npm scripts详解_字段_24

上面代码中,变量 npm_package_config_port 对应的就是 3001。


5. 通配规则

  • * 匹配 0 个或多个字符

  • ? 匹配 1 个字符

  • [...] 匹配某个范围的字符。如果该范围的第一个字符是 ! 或 ^ ,则匹配不在该范围的字符。

  • !(pattern|pattern|pattern) 匹配任何不符合给定的模式

  • ?(pattern|pattern|pattern) 匹配 0 个或 1 个给定的模式

  • +(pattern|pattern|pattern) 匹配 1 个或多个给定的模式

  • *(a|b|c) 匹配 0 个或多个给定的模式

  • @(pattern|pat*|pat?erN) 只匹配给定模式之一

  • ** 如果出现在路径部分,表示0个或多个子目录。



关于本文

作者:@yangfch3