发布于 

前端工程化并行解决方案-concurrently

一、介绍

主要是方便我们写前端工程化的时候,我们可以同时启动多个命令用。
比如我的前端代码运行起来,既要有一个web工程,同时又要启动一个mock进程。这时候我们就可以使用这个并行解决方案。
文档地址:https://www.npmjs.com/package/concurrently
github地址:https://github.com/kimmobrunfeldt/concurrently
截止2019年5月13日.
各项指标: star数量2669,issue数量在100左右

img

周下载量:39万

img

二、安装

2.1 全局安装

2.2 项目安装

以上果是开发阶段写工具用的时候的安装方法。
如果比如node项目在生产环境使用则用以下安装方法:

三、使用方法

3.1 命令行使用方式

语法:

1
concurrently "command1 arg" "command2 arg"

比如我要启动两个node程序:

img

然后当我们ctrl + c后,他就会把两个进程都停止了。

img

方式1:

如果我们在package.json里面则要注意引号的问题:

1
"start": "concurrently \"command1 arg\" \"command2 arg\""

就是将”变成".

方式2:


img

然后我们要让这个进行并行有两个方式,在命令行执行:

img

或者:

img

这块-n之后的两个单词,只能用,间隔,不能加空格。

方式3:

如果我们的package.json里面有以下三个watch类型的

1
2
3
4
5
6
7
8
9
10
11
{
//...
"scripts": {
// ...
"watch-js": "...",
"watch-css": "...",
"watch-node": "...",
// ...
},
// ...
}

那可以批量执行的方式:

1
2
3
4
5
6
7
8
9
10
11
12
concurrently "npm:watch-*"

# Equivalent to:
concurrently -n js,css,node "npm run watch-js" "npm run watch-css" "npm run watch-node"

# Any name provided for the wildcard command will be used as a prefix to the wildcard
# part of the script name:
concurrently -n w: npm:watch-*

# Equivalent to:

concurrently -n w:js,w:css,w:node "npm run watch-js" "npm run watch-css" "npm run watch-node"

3.2 代码方式使用

3.2.1 构建成功场景

然后我们可以书写一个node程序来调用concurrently。
我们写一个main.js的代码

1
2
3
4
5
6
7
var concurrently = require('concurrently');

concurrently(['npm:index', "npm:hello"]).then(()=>{
console.log("success");
}, ()=>{
console.log("fail")
});

然后它的效果,就是concurrently "npm:index" "npm:hello"
然后当我们按了ctrl + c之后,他会打出success.

img

上面的index和hello对应的代码是:
index:

1
2
3
4
5
6
7
8
9
10
var koa = require('koa');
var axios = require('axios')

const app = new koa();

app.use(async (ctx, next)=>{
ctx.body = (await axios.get("http://127.0.0.1:8001/hello")).data;
})

app.listen(8000)

hello:

1
2
3
4
5
6
7
8
9
var koa = require('koa');

const app = new koa();

app.use((ctx, next)=>{
ctx.body = 'hello world2';
})

app.listen(8001)

3.2.2 构建失败场景

我们修改上面的hello的代码:
hello:

1
2
3
4
5
6
7
8
9
var koa = require('koa');

const app = new koa();

app.use((ctx, next)=>{
ctx.body = 'hello world2';
})

process.exit(-1);

然后我们在运行"node ./main.js"
我们会看到报错,但是程序不会退出。

img

然后当我们再按ctrl + c后,效果如下:

img

所以得出一个结论:当我们有一个进程返回失败的话,总体会进入fail的callback中。

img

四、原理

4.1 启动进程原理

img

这块代码比较好理解,这块基本是用spawn去启动进程。
但是这块关于nodejs中,应用了rxjs,这个有学习的地方。
就是后期在node代码中也可以看看rxjs的应用。

4.2 启动进程的spawn

默认使用的是spawn-command,同时我们也可以传入我们的options.spawn来替换。

4.3 如何杀进程

通过treeKill这个npm包来处理。

五、应用场景

5.1 开发工具

比如当我们跑npm run start的时候,我们同时需要让sass编译,同时webpack也要跑hot 模式,则这个使用可以使用concurrently运行这两个command。
这块我们可以查看grafana里面的前端代码中,关于工具这块代码查看一下就可以看到这块的使用。
grafana地址: https://github.com/grafana/grafana

六、常见需求

6.1 当一个进程起来失败,整体concurrently失败?


img

我们可以通过killOthers这个参数来解决。

这样当我们有一个程序失败,则直接进入fail callback。也就把所有进程关闭了。

6.2 当一个进程起来失败,但是有可能是跟另外进程有关,这时候需要尝试几次?

img

这种情况,如上比如npm:index能启动的,npm:hello不能启动,虽然试了三次npm:hello,一直失败,但整体最终不会退出,只有我们按ctrl + c才有用,相当于killOthers就失效了。

七、参考文档

grafana的前端源码里面有用: https://github.com/grafana/grafana
npm官网的readme: https://www.npmjs.com/package/concurrently
github的源码: https://github.com/kimmobrunfeldt/concurrently


如果你有什么意见和建议,可以点击: 反馈地址 进行反馈。