본문 바로가기
개발 기록

Node.js 로 CLI 프로그램 만들기 - 2. 직접 만들어보기

by 유세지 2020. 3. 2.

 

Node.js 로 CLI 프로그램 만들기 - 1. 강좌 따라가기에 이어서 직접 프로그램을 하나 짜보도록 하겠다.

 

Node.js 로 CLI 프로그램 만들기 - 1. 강좌 따라가기

이 글은 zerocho님의 Node.js 강의 영상을 참고하여 진행하였습니다. 아래 예제들과 설명은 이 강의에 출처가 있음을 밝힙니다.(https://osam.kr/learn/lecture/15158/%EC%9E%90%EC%9C%A0%EA%B3%BC%EC%A0%95-web%E..

usage.tistory.com

강좌로 배웠던것을 복습하는 수준이니 복잡한 프로그램은 아니고, 말 그대로 잘 공부했는지 간단한 퀴즈를 통해 맞춰보는 프로그램이다.

 

첫 화면에서는 공부하기, 퀴즈풀기 두 가지 선택지를 주고, 공부하기를 선택하면 배웠던 내용을 다시 볼 수 있도록 짜고 퀴즈풀기를 선택하면 바로 문제를 풀 수 있도록 넘어가게 하려고 한다.

 

우선 필요한 모듈들을 불러주었다.

const program = require('commander');
const inquirer = require('inquirer');
const chalk = require('chalk');

 

이전 게시물에서 배웠던 commander, inquirer, chalk 세 가지 모듈이다.

각각 program, inquirer, chalk 의 이름을 가진 const 로 선언해주었다.

var이나 let으로 해도 작동은 하겠지만 ES6 문법에 적응하는 연습도 할겸 표준에 맞추어서 짜보았다.

 

let triggered = false;

program
	.version('0.1', '-v, --version')
	.usage('[options]')
	.command('quiz')
	.action(() => {
		triggered = true;
	});

program.parse(process.argv);

if(!triggered) {
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: 'CLI에 오신것을 환영합니다. 메뉴를 선택하세요.',
		choices: ['공부 하기', '퀴즈 풀기'],
	}])
	.then((answers) => {
		console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
		selected(answers.menu);
	})
}

 

program ( commander.js ) 의 속성을 설정해주는 것으로 시작한다.

버전과 실행 내용등을 지정해주고, 실행되었을때 triggered 변수를 true로 바꾸어 inquirer 단이 실행되도록 해주었다.

동시에 선택한 메뉴를 출력해주며 chalk를 이용하여 초록색으로 강조해주었다.

 

코드 중 .action에 붙어있는 => 이 기호는 화살표 함수(arrow function) 라고 하는데 이것도 ES6 문법의 일종이다.

다음 기회에 ES6 문법도 쭉 정리해보아야겠다.

 

const selected = (menu) => {
	if (menu === '퀴즈 풀기') {
		takeQuiz();
	}else if (menu === '공부 하기') {
		study();
	}
}

 

사용자의 선택에 따라 어떤 동작을 할지 정해주었다.

퀴즈 풀기를 선택했을경우 takeQuiz() 함수로, 공부 하기를 선택했을경우 study() 함수로 넘어가게 된다.

 

const study = () => {
	let description = '\n기본적인 commander 명령어에 대해 알아봅시다.\n\n.command : 실행 명령어\n.version : 프로그램의 버젼\n.usage : 사용법\n.description : 해당 명령어 설명\n.alias : 별명, 이 프로그램을 실행하는 명령어의 약어\n.option : 기능 명령어\n.action : 실행 내용\n';
	console.log(description);
	
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: '메뉴를 선택하세요.',
		choices: ['공부 하기', '퀴즈 풀기'],
	}])
	.then((answers) => {
		console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
		selected(answers.menu);
	})
}

 

공부하기를 선택하면 넘어가는 함수이다.

전 장에서 배웠던 내용들을 출력해주고, 출력이 끝나면 처음 화면에서 보았던 선택지를 보여주어 프로그램이 종료되지 않도록 해준다.

이제와서 생각해보니 이 부분도 함수로 감싸서 재사용 할 수 있지 않을까 하는 아쉬움이 든다.

 

const takeQuiz = () => {
	let score = 0;
	console.log('CLI 퀴즈에 오신것을 환영합니다. 아래 보기 중 정답을 골라주시면 됩니다.\n');
	
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: '준비되셨나요?',
		choices: ['예', '아니요'],
	}])
	.then((answers) => {
		quizSelected(answers.menu);
	})
	
	const calculate = (answers) => {
		let finalscore = 0;
		if(answers.q1 === 'commander') finalscore += 1;
		if(answers.q2 === 'version') finalscore += 1;
		if(answers.q3 === 'usage') finalscore += 1;
		if(answers.q4 === 'description') finalscore += 1;
		if(answers.q5 === 'alias') finalscore += 1;
		if(answers.q6 === 'option') finalscore += 1;
		if(answers.q7 === 'action') finalscore += 1;
		return finalscore;
	}
	
	const quizSelected = (menu) => {
		if (menu === '예') {
			console.clear();
			inquirer.prompt([{
				type: 'list',
				name: 'q1',
				message: 'Q1. commander의 프로그램 실행문을 지정하는 명령어는?',
				choices: ['execute', 'commander'],
			}, {
				type: 'list',
				name: 'q2',
				message: 'Q2. commander의 프로그램 버전을 확인하는 명령어는?',
				choices: ['version', 'bersion'],
			}, {
				type: 'list',
				name: 'q3',
				message: 'Q3. commander의 사용법을 작성하는 명령어는?',
				choices: ['howto', 'usage'],
			}, {
				type: 'list',
				name: 'q4',
				message: 'Q4. commander의 명렁어 설명을 작성하는 명령어는?',
				choices: ['script', 'description'],
			}, {
				type: 'list',
				name: 'q5',
				message: 'Q5. commander의 프로그램 실행 명령어의 약어를 지정하는 명령어는?',
				choices: ['vision', 'alias'],
			}, {
				type: 'list',
				name: 'q6',
				message: 'Q6. commander의 기능을 명명하는 명령어는?',
				choices: ['option', 'operation'],
			}, {
				type: 'list',
				name: 'q7',
				message: 'Q7. commander의 명령어 실행 내용을 작성하는 명령어는?',
				choices: ['behaivor', 'action'],
			}])
			.then((answers) => {
				console.clear();
				score = calculate(answers);
				console.log("당신의 점수는 " + chalk.green(score) + "점 입니다!");
			})
		}else if (menu === '아니요') {
			console.clear();
			inquirer.prompt([{
				type: 'list',
				name: 'menu',
				message: '메뉴를 선택하세요.',
				choices: ['공부 하기', '퀴즈 풀기'],
			}])
			.then((answers) => {
				console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
				selected(answers.menu);
			})
		}
	}
}

 

이 프로그램의 하이라이트 퀴즈 풀기 부분이다.

퀴즈를 풀 것인지 먼저 물어보고, 아니요를 선택하면 메인으로 돌아가게 하였다.

예를 선택하면 console.clear()를 이용해 콘솔창을 정리하고 퀴즈를 하나씩 출력한다.

풀이가 끝나면 calculate 함수에 응답한 내용을 매개변수로 전해주고, 풀이에 대한 점수를 리턴받아 표시한다.

 

코드 길이가 좀 길어졌는데 문제 내용 때문에 어쩔 수 없는 부분이었다.

다만 inquirer 덕분에 보고 내용을 파악하기가 상당히 편했다.

 

 

아래는 코드 전문이다.

 

const program = require('commander');
const inquirer = require('inquirer');
const chalk = require('chalk');

// *
// * CLI 메소드 퀴즈 프로그램
// *
// * 기본적인 CLI 메소드의 사용법을 공부해봅시다.
// *

const takeQuiz = () => {
	let score = 0;
	console.log('CLI 퀴즈에 오신것을 환영합니다. 아래 보기 중 정답을 골라주시면 됩니다.\n');
	
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: '준비되셨나요?',
		choices: ['예', '아니요'],
	}])
	.then((answers) => {
		quizSelected(answers.menu);
	})
	
	const calculate = (answers) => {
		let finalscore = 0;
		if(answers.q1 === 'commander') finalscore += 1;
		if(answers.q2 === 'version') finalscore += 1;
		if(answers.q3 === 'usage') finalscore += 1;
		if(answers.q4 === 'description') finalscore += 1;
		if(answers.q5 === 'alias') finalscore += 1;
		if(answers.q6 === 'option') finalscore += 1;
		if(answers.q7 === 'action') finalscore += 1;
		return finalscore;
	}
	
	const quizSelected = (menu) => {
		if (menu === '예') {
			console.clear();
			inquirer.prompt([{
				type: 'list',
				name: 'q1',
				message: 'Q1. commander의 프로그램 실행문을 지정하는 명령어는?',
				choices: ['execute', 'commander'],
			}, {
				type: 'list',
				name: 'q2',
				message: 'Q2. commander의 프로그램 버전을 확인하는 명령어는?',
				choices: ['version', 'bersion'],
			}, {
				type: 'list',
				name: 'q3',
				message: 'Q3. commander의 사용법을 작성하는 명령어는?',
				choices: ['howto', 'usage'],
			}, {
				type: 'list',
				name: 'q4',
				message: 'Q4. commander의 명렁어 설명을 작성하는 명령어는?',
				choices: ['script', 'description'],
			}, {
				type: 'list',
				name: 'q5',
				message: 'Q5. commander의 프로그램 실행 명령어의 약어를 지정하는 명령어는?',
				choices: ['vision', 'alias'],
			}, {
				type: 'list',
				name: 'q6',
				message: 'Q6. commander의 기능을 명명하는 명령어는?',
				choices: ['option', 'operation'],
			}, {
				type: 'list',
				name: 'q7',
				message: 'Q7. commander의 명령어 실행 내용을 작성하는 명령어는?',
				choices: ['behaivor', 'action'],
			}])
			.then((answers) => {
				console.clear();
				score = calculate(answers);
				console.log("당신의 점수는 " + chalk.green(score) + "점 입니다!");
			})
		}else if (menu === '아니요') {
			console.clear();
			inquirer.prompt([{
				type: 'list',
				name: 'menu',
				message: '메뉴를 선택하세요.',
				choices: ['공부 하기', '퀴즈 풀기'],
			}])
			.then((answers) => {
				console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
				selected(answers.menu);
			})
		}
	}
}

const study = () => {
	let description = '\n기본적인 commander 명령어에 대해 알아봅시다.\n\n.command : 실행 명령어\n.version : 프로그램의 버젼\n.usage : 사용법\n.description : 해당 명령어 설명\n.alias : 별명, 이 프로그램을 실행하는 명령어의 약어\n.option : 기능 명령어\n.action : 실행 내용\n';
	console.log(description);
	
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: '메뉴를 선택하세요.',
		choices: ['공부 하기', '퀴즈 풀기'],
	}])
	.then((answers) => {
		console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
		selected(answers.menu);
	})
}

const selected = (menu) => {
	if (menu === '퀴즈 풀기') {
		takeQuiz();
	}else if (menu === '공부 하기') {
		study();
	}
}

let triggered = false;

program
	.version('0.1', '-v, --version')
	.usage('[options]')
	.command('quiz')
	.action(() => {
		triggered = true;
	});

program.parse(process.argv);

if(!triggered) {
	inquirer.prompt([{
		type: 'list',
		name: 'menu',
		message: 'CLI에 오신것을 환영합니다. 메뉴를 선택하세요.',
		choices: ['공부 하기', '퀴즈 풀기'],
	}])
	.then((answers) => {
		console.log(chalk.green(answers.menu) + "를 선택하셨습니다.");
		selected(answers.menu);
	})
}

 

 

자바스크립트로는 처음 만들어보는 CLI 프로그램인데 상당히 매력적이고 재밌다. 군 입대 후 터미널이나 파워쉘, 명령프롬프트를 쓸 일이 부쩍 많아졌는데 앞으로도 자주 쓰게 될 것 같은 느낌이 든다.

 

 

전체 프로젝트 파일들은 여기에서 확인할 수 있다.

 

kyr9389/Practice_NodeCLI

CLI program practice with node.js. Contribute to kyr9389/Practice_NodeCLI development by creating an account on GitHub.

github.com

 

반응형

댓글