All Articles

허선생님과 함께하는 node를 이용해 랜덤 빙고판 만들고 md파일 생성

image.png

빙고테이블을 만들어서 사람들의 repo에 README.md파일을 뿌리는게 내 목표였다.

처음엔 숫자를 랜덤으로 뿌려서 테이블에 적용시키면 되는거네?하고 그냥 쉽게 생각했는데
md파일에 랜덤 만드는 js문법을 쓸 수도 없고 어쩌지?? 하고 발만 동동 구르고 있었는데

정답은 node 에 있었다.
허선생님의 도움으로 해결쓰..ㅠㅠ

빙고 table을 만들어보자.

코드를 간략하게 하기위해 utils에 필요한 함수들을 저장해서 불러왔다.
utils는 map과 같은 array method들 뿐만 아니라 랜덤한 값을 뽑아내는 shuffle method를 포함쓰

//table.js
const utils = require('./utils');

const makeTable = utils.pipe(
  () => Array(25),
  (arr) => arr.fill(),
  utils.map((e, i) => i + 1),
  utils.shuffleArray,
  (arr) =>
    utils.pipe(
      (arr) => arr.fill(),
      utils.map((e, i) => i),
      utils.reduce((acc, curr) => {
        const index = curr * 5;
        return [...acc, arr.slice(index, index + 5)];
      }, [])
    )(Array(5)),
  utils.map((row) => {
    return [
      '<tr>',
      row.map((cell) => `    <td>${cell}</td>`).join('\n'),
      '</tr>',
    ].join('\n');
  }),
  (arr) => ['<table>', '<tbody>', ...arr, '</tbody>', '</table>'],
  (arr) => arr.join('\n')
);

module.exports = { makeTable };

코드를 하나하나 살펴보자.

1~25까지의 숫자가 들어간 배열 만들기

// 파이프라인의 첫 시작
() => Array(25),
  arr => arr.fill(),
  utils.map((e, i) => i + 1),
  1. Array(25)를 이용해 빈 배열에 25개의 값이 들어갈 자리를 만들어주고
  2. fill()을 이용해서 빈 공간을 undefined로 채우기
  3. map의 index number를 이용해 배열을 숫자로 채우기

위의 코드는 파이프라인에 들어가는 거라 쉼표로 길게 쓴 거지만 만약에 파이프에 들어가지 않고 따로 썼다면 한줄로도 가능쓰!

Array(25).fill().map((e,i)=>i+1) 요렇게!

배열 속 25개 숫자들을 섞어주기

stackoverflow를 찾다보면 괜찮은 랜덤함수들이 많다.
내가 짜는건 머리아플 수 있으니 다른 사람이 짜놓은 좋은 로직의 함수를 저장해서 써먹자! 그리하여 간단하게 utils.shuffleArray, 요렇게 끝!

여기까진 쉬울수도 있다. 하지만 내가 해야할 것은 테이블에 숫자를 넣는건데
<tr></tr>태그로 감싸야 하기 때문에 숫자 5개를 각각의 tr태그 안에 넣어야 한다.

여기서 난 멘붕을 당했고, 허선생님은 간단하게 파이프를 한번 더 썼다…ㅋㅋ ㅠㅠ

위에서 만든 배열 속 숫자를 다섯개씩 끊어주기

 arr => utils.pipe(
      arr => arr.fill(),
      utils.map((e, i) => i),
      utils.reduce((acc, curr) => {
        const index = curr * 5
        return [
          ...acc,
          arr.slice(index, index + 5),
        ]
      }, []),

파이프를 한번 더 써주는데 아까처럼 fill을 이용해 배열의 빈 공간을 확보해놓고
map의 index number를 이용해서 0부터 4까지의 숫자를 뽑아냈고(배열 5개 필요하니깐) reduce 부분은 넘 헷갈려서 콘솔을 찍어봤다.

image.png

숫자를 5개씩 끊어야해서 slice를 써주는데 이를 쉽게하기 위해 index를 선언해주었고
acc는 빈배열에서 숫자가 채워지는 형태로, curr은 현재 배열이 속한 index를 가리켰다.
다시 보니 reduce 쪽이 잘 이해가 되지 않는다… ㅠㅠ

여튼 slice를 이용해서 5개씩 자른 배열을 만든다고 대충 이해 했고..

자른 숫자에 테이블 태그 적용하기

let row = [4, 9, 14, 22, 16];
['<tr>', row.map((cell) => `    <td>${cell}</td>`).join('\n'), '</tr>'].join(
  '\n'
);

정확한 로직은 제일 위의 코드 참고!
나는 일단 이게 잘 적용 되는지 확인하고 싶어서 임의의 배열을 row 변수에 대입했다.
사실 안쪽의 join은 안 써도 상관없긴 한데 확실이 indent가 있으니 보기 편하다!

결과물은 이렇게…

image.png

이걸 이제 <table>태그와 <tbody>태그 안에 넣어주는건 완전 쉽다!
html 태그를 배열을 이용해서 적용하는건 생각지도 못했는데 정말 신박한 방법이였다ㅠㅠ 커링 두 번 쓴 것보다 html태그 적용한게 더 신기했다.. 와 ㅠㅠ

이제 fs에 적용을 해야하는데..

node file system

// fs.js
const fs = require('fs');

const read = (path) =>
  new Promise((resolve, reject) => {
    fs.readFile(path, 'utf8', (err, data) => {
      if (err) return reject(err);
      return resolve(data);
    });
  });

const write = (path, data) =>
  new Promise((resolve, reject) => {
    fs.writeFile(path, data, (err) => {
      if (err) return reject(err);
      return resolve(true);
    });
  });

module.exports = {
  read,
  write,
};

여기서 중요한 건 읽기모드와 쓰기모드 둘 다 적용시켜야 한다는 점!
일단 fs 형식을 위의 코드와 같이 써주고 우리는 이걸 index.js에서 적용시킬 예정쓰

md파일 생성하기

아! 이 전에 template md 파일을 만들어야 하는데!

title~~

<<<table>>>

description....

빙고판을 중간에 낑겨넣고 싶어서 일단 꺽쇠를 이용해서 영역표시(?)를 해주고…

const fs = require('./fs');
const path = require('path');
const { makeTable } = require('./table');

fs.read(path.join(__dirname, './README.template.md'))
  .then((data) => {
    const newContent = data.replace('<<<table>>>', makeTable());
    return newContent;
  })
  .then((content) => {
    fs.write(path.join(__dirname, '../README.md'), content).then(() => {
      console.log('README 저장됨~~😆');
    });
  });

replace를 이용해 <<<table>>>이라는 글씨를 우리가 만든 빙고로 대체해준다.
그리고 path 설정을 잘 해줘야 하는데..!
첫번째 인자에 __dirname이 들어가지 않으면 작동이 안됐던 기억이..
두번째 인자는 경로와 파일이름과 형식이 들어가게 된다.

처음에는 이렇게 node server를 켤 때마다 파일을 하나씩 생성하는 로직이었는데
우리의 능력자 허선생님이 로직을 바꿔서 각폴더에 각 md파일이 들어가게끔 해서
서버 한 번 켰을때 39개의 폴더와 md파일들이 한번에 생성되도록 만들어주었다.

한 1초? 늦어도 1.5초 걸렸을까..?

이래서 노드를 쓰나보다.. 정말 정말 빠르고 편리하다..
노드의 매력에 점점 빠지고 있는 요즘이다.

아.. 공부 진짜 열심히 하자ㅠㅠ 갈 길이 멀었다!!!

Reference

  • 허선생님의 손길