16

什么是child_process

child_process模块是nodejs的一个子进程模块,可以用来创建一个子进程,并执行一些任务。执行一些什么任务呢?shell命令知道吧,有了child_process模块,就可以直接在js里面调用shell命令去完成一些非常酷炫的操作了!!
举个栗子,GitHub码云等git代码托管网站,都会有个webHook功能,当push了新的代码后,服务器可以开辟一个接口去接受这个webHook的请求,并进行git pullnpm run build等命令,从而达到自动化部署的目的!

码云的webHook功能

来个小demo

目录结构

前端直接简单用的vue-cli脚手架新建了个项目,后端是用的express

clipboard.png

前端代码就不晒了,都是脚手架生成的,后端代码主要就是一个server.js和一个执行shell的方法。

backend/server.js

backend/server.js
注意先要安装几个依赖:expressbody-parser
express是主角,不用多说,body-parser是用来解析post请求的参数的。
const express = require('express');
const app = express();
const port = process.env.PORT || 8080;
const www = process.env.WWW || './fontend/dist';
var bodyParser = require('body-parser')//格式化body数据

app.use(bodyParser.urlencoded({extended: false}));//body parser插件配置
app.use(bodyParser.json());//body parser插件配置
const gitPush = require('./service/git-push')//引入写的服务

app.post('/api/git_hook',async (req, res) => {//监听这个接口
    if(req.body.password !== '666'){// 这里校验post请求的密码
        res.send('密码错误')
        return 
    }
    const code = await gitPush()
    res.send('hello world' + code)
})
app.use(express.static(www));
console.log(`serving ${www}`);


app.get('*', (req, res) => {
    res.sendFile(`index.html`, { root: www });
});
app.listen(port, () => console.log(`listening on http://localhost:${port}`));

backend/service/git-push.js

const childProcess = require('child_process');
const path = require('path')

module.exports = async function (params) {
    await createGitPullPromise()
    return await createPackPromise()
}
function createPackPromise(){
    return new Promise((res, rej) => {
        const compile = childProcess.spawn('npm', ['run', 'build'], {cwd: path.resolve(__dirname, '../../fontend')})
        compile.on('close', code => {
            // console.log(code)
            res(code)
        })
    })
}
function createGitPullPromise(){
    return new Promise((res, rej) => {
        const compile = childProcess.spawn('git', ['pull'], {cwd: path.resolve(__dirname, '../../fontend')})
        compile.on('close', code => {
            // console.log(code)
            res(code)
        })
    })
}

小结

child_process模块,主要是用的child_process.spawn(),需要注意的是,这个函数只会创建异步进程,具体的API可以参考官网。异步进程的话,不会阻塞主进程的执行,所以我backend/service/git-push.js里面用async function来进行异步回调的控制。child_process模块还提供了创建同步子进程的方法 child_process.spawnSync,了解nodejs比较多的同学可能会发现,跟异步的方法相比,就是最后面加了个Sync,嗯,也可以这么理解吧。
希望大家多了解下这个模块,多动手操作下,能用到哪里 留下了非常大的想象空间!


ovensi
1.6k 声望261 粉丝