通过​​npm run <commander>​​​ 可以运行 ​​package.json​​ 中脚本,Npm 命令不能提供立即运行多个脚本的方式,同时运行需要打开多个终端窗口

npm scripts

  • ​node_modules/.bin​​ 目录下的命令,可以直接在 scripts 中调用
  • 利用一些脚本生命周期时间
"scripts": {
"preinstall": "./configure",
"install": "make && make install"
}

​make​​​ (​​npm run install​​​)前后自动执行 ​​./configure​​​ (​​npm run preinstall​​)。注意的是,官方并不提倡在 scripts 中定义 install

  • 可以通过​​process.env.npm_package_scripts_<commander>​​ 查看 scripts 中的命令情况
"scripts": {
"test": "node test.js"
}

​process.env.npm_package_scripts_test === 'node test.js'​

  • ​npm run​​​ 从根目录运行,不管调用的当前目录是什么(​​process.env.PWD​​​ 一直指向根目录)。可以通过 ​​process.env.INIT_CWD​​ 获得所处的完整路径。
  • 清除缓存
$ npm cache clean --force
$ yarn cache clean

问题

下述通过 Bash 来实现的

"scripts": {
"deploy": "vue-cli-service build & vue-cli-service build screen && node deploy.js"
}

期望: 并发执行​​vue-cli-service build​​​ 和 ​​vue-cli-service build screen​​​ ;执行完后再执行 ​​node deploy.js​

实际: 并发执行 ​​vue-cli-service build​​​ 和 ​​vue-cli-service build screen && node deploy.js​

简化示例,进行实验讨论

示例

1.js

#!/usr/bin/env node
setTimeout(() => {
console.log('1')
}, 6000)

2.js

setTimeout(() => {
console.log('2')
}, 3000)

3.js

setTimeout(() => {
console.log('3')
}, 1000)

Bash

命令

说明

​&&​

顺序执行多条命令,当碰到执行出错的命令后将不执行后面的命令

​&​

并行执行多条命令

​||​

顺序执行多条命令,当碰到执行正确的命令后将不执行后面的命令

​|​

管道符

&&

"scripts": {
"test": "node ./build/1.js && node ./build/2.js && node ./build/3.js"
}

顺序执行多条命令,输出结果:1 2 3

&

"scripts": {
"test": "node ./build/1.js & node ./build/2.js & node ./build/3.js"
}

并行执行多条命令,输出结果:3 2 1

||

"scripts": {
test": "node ./build/1.js || node ./build/2.js || node ./build/3.js"
}

输出结果:1

执行正确后不会执行后面的命令,何谓成功or失败呢?

Bash:成功 ​​exit 0​​​;失败(非0) ​​exit 1​

Nodejs:成功 ​​process.exit(0)​​​;失败(非0) ​​process.exit(1)​

先并行后串行?

"scripts": {
"test": "node ./build/1.js & node ./build/2.js && node ./build/3.js"
}

输出结果:2 3 1 惊喜不惊喜(并不是预期的 2 1 3)!你可能会说,是以为优先级的问题导致的,应该这样:

"scripts": {
"test": "(node ./build/1.js & node ./build/2.js) && node ./build/3.js"
}

你想多了,输出结果仍然是:2 3 1

注意,上述在window下不能生效!

concurrently

跨平台,同时运行多个命令(并发)。

"scripts": {
"test": "concurrently \"node ./build/1.js\" \"node ./build/2.js\" \"node ./build/3.js\""
}

并行执行多条命令,输出结果:3 2 1

只能并行,不能顺序执行!

npm-run-all

跨平台,一种可以并行或顺序运行多个 npm 脚本的 CLI 工具。

  • ​npm-run-all​​ 综合性命令(可顺序可并行)
  • ​run-s​​​ 简写,等价于 ​​npm-run-all -s​​ 顺序(sequentially)运行 npm-scripts
  • ​run-p​​​ 简写,等价于 ​​npm-run-all -p​​ 并行(parallel)运行 npm-scripts
"script": {
"n_1": "node ./build/1.js",
"n_2": "node ./build/2.js",
"n_3": "node ./build/3.js",
"test": "npm-run-all -p n_1 n_2 -s n_3",
}

输出结果:2 1 3(并行执行n_1、n_2;然后执行n_3

npm-run-all 还具备支持参数传递;错误退出控制;提供 Node Api ;以及一些优化项​​npm-run-all --parallel dev:**​​等。

注意,npm-run-all node 方式不支持,其实针对 npm scripts 并发和顺序执行的解决方案;但对于 Yarn 同样支持!

借助 scripts 生命周期事件关系

通过 ​​npm-run-all​​ 可以启发我们,可以通过 scripts 的一些属性关系来达到顺序执行。

"scripts": {
"prepack": "concurrently \"node ./build/1.js\" \"node ./build/2.js\"",
"pack": "node ./build/3.js",
}

prepack: run BEFORE a tarball is packed (on ​​npm pack​​​, ​​npm publish​​, and when installing git dependencies)

注意,只提供一种思路,并不提倡大家使用。因为内置的事件名称本身就有一定的特定意义

其他

目前社区还有类似的一些开源处理方式(​​shell-executor​​​ 、​​npm-parallel​​ )等等,实现方式基本大同小异,感兴趣的小伙伴可自行查阅!

相关地址