[Nodejs] 커맨드 동시 실행으로 커밋 검사 속도 향상
프로젝트에서 githook을 이용해 커밋 전 검사를 하고 있다.
yarn eslint ./src --cache && tsc --noEmit && yarn test
3개의 커맨드가 모두 정상적으로 종료되어야만 커밋되고,
이 작업들은 현재 의존성을 가지고 있어 이전 작업이 끝나야만 다음 커맨드가 실행된다.
(yarn eslint ... > tsc ... > yarn test...)
정말 의존성이 필요할까?
eslint는 js, jsx파일의 코드 포맷 검사,
tsc는 ts, tsx파일의 코드 유효성 검사,
test는 테스트를 수행한다.
사실 이들의 순서가 바뀌어도 상관없고,
심지어는 동시에 실행되어도 결과에는 영향을 미치지 않는다.
위 명령을 실행하면 약 20~30초가량이 소모되는데,
점점 프로젝트의 규모가 커짐에 따라 시간이 오래 걸리다 보니 커밋 전 검사에 짜증이 날 지경까지 왔다.
동시에 실행해보자
//parallel-command.js
const { spawn } = require("child_process");
const runCmd = (cmd, args) => {
if (!cmd) {
console.error("There is no cmd");
process.exit(-1);
}
console.log("run command: ", cmd, ...args);
const ls = spawn(cmd, args);
ls.stdout.on("data", data => {
console.log(`${data}`);
});
ls.stderr.on("data", data => {
console.error(`${data}`);
});
ls.on("error", error => {
console.log(`error: ${error.message}`);
});
ls.on("close", code => {
console.log(`child process exited with code ${code}`);
if (code !== 0) {
process.exit(code);
}
});
return ls;
};
const runnings = [];
process.argv.slice(2).reduce(
(acc, arg, index, inputArgs) => {
const { cmd, args } = acc;
if (index + 1 >= inputArgs.length || arg === ",") {
const running = runCmd(cmd, arg === "," ? args : [...args, arg]);
runnings.push(running);
return {
cmd: "",
args: []
};
}
if (!cmd) {
return {
cmd: arg,
args: []
};
} else {
return { ...acc, args: [...args, arg] };
}
},
{
cmd: "",
args: []
}
);
process.on("SIGINT", () => {
//all kill
runnings.map(running => running.kill("SIGINT"));
});
spawn을 이용해 받아들인 프로세스의 갯수만큼 child process를 만들고 동시에 실행시킨 후
프로세스가 0이 아닌 코드로 종료되면, parent process (parallel-command를 실행중인 node 프로세스)도 그 코드로 종료하게 했다.
사용할 때는
node parallel-command.js [CMD...] , [CMD...]
처럼 사용한다.
커맨드의 구분은 , 로 하며 한 칸씩 띄워야 한다.
예를 들어, 맨 위의 커맨드는 아래처럼 바꿔 쓸 수 있다.
time node parallel-command.js yarn eslint ./src --cache , tsc --noEmit , yarn test
이제 세 개의 커맨드가 동시에 실행될 것이다.
7초면 끝난다.
단점
원래 커맨드를 실행했을 때 출력되는 텍스트의 스타일이 무시된다.
이렇게 형형색색으로 예쁘게 나오던 출력이
기본 색상으로만 흐리멍텅하게 나온다.
근데 나한테 중요한 것은 이 검사가 주는 메시지가 아니라 검사 통과 여부였기 때문에 상관없었다.