前端工程化并行解决方案-concurrently
一、介绍
主要是方便我们写前端工程化的时候,我们可以同时启动多个命令用。
比如我的前端代码运行起来,既要有一个web工程,同时又要启动一个mock进程。这时候我们就可以使用这个并行解决方案。
文档地址:https://www.npmjs.com/package/concurrently
github地址:https://github.com/kimmobrunfeldt/concurrently
截止2019年5月13日.
各项指标: star数量2669,issue数量在100左右
周下载量:39万
二、安装
2.1 全局安装
2.2 项目安装
以上果是开发阶段写工具用的时候的安装方法。
如果比如node项目在生产环境使用则用以下安装方法:
三、使用方法
3.1 命令行使用方式
语法:
1
| concurrently "command1 arg" "command2 arg"
|
比如我要启动两个node程序:
然后当我们ctrl + c后,他就会把两个进程都停止了。
方式1:
如果我们在package.json里面则要注意引号的问题:
1
| "start": "concurrently \"command1 arg\" \"command2 arg\""
|
就是将”变成".
方式2:
然后我们要让这个进行并行有两个方式,在命令行执行:
或者:
这块-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.
上面的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"
我们会看到报错,但是程序不会退出。
然后当我们再按ctrl + c后,效果如下:
所以得出一个结论:当我们有一个进程返回失败的话,总体会进入fail的callback中。
四、原理
4.1 启动进程原理
这块代码比较好理解,这块基本是用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失败?
我们可以通过killOthers这个参数来解决。
这样当我们有一个程序失败,则直接进入fail callback。也就把所有进程关闭了。
6.2 当一个进程起来失败,但是有可能是跟另外进程有关,这时候需要尝试几次?
这种情况,如上比如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