.md 파일 파싱해서 객체로 저장하는 방법 (js)

호이초이·2024년 11월 8일
0
post-thumbnail

우테코 프리코스 4주차 과제의 명세를 읽던 중, 마크다운 파일로 주어진 메뉴 목록과 프로모션 혜택을 이용해야했다. 처음 이해했을 땐, 단순히, 마크다운 파일에 있는 텍스트를 가져다가 객체로 만들면 되나? 라고 생각했다.
다시 명세를 제대로 읽어보니, 상품 목록과 행사 목록을 파일 입출력을 통해 불러온다라고 나와있었다.! 이 소리는 직접 마크다운 파일을 불러와 가공해서 사용하라라는 뜻이었다! 그래서 처음 마크다운 파일을 가공하는 작업을 시도 해보려 한다.

주어진 파일

products.md 파일

name,price,quantity,promotion
콜라,1000,10,탄산2+1
콜라,1000,10,null
사이다,1000,8,탄산2+1
사이다,1000,7,null
오렌지주스,1800,9,MD추천상품
탄산수,1200,5,탄산2+1
물,500,10,null
비타민워터,1500,6,null
감자칩,1500,5,반짝할인
감자칩,1500,5,null
초코바,1200,5,MD추천상품
초코바,1200,5,null
에너지바,2000,5,null
정식도시락,6400,8,null
컵라면,1700,1,MD추천상품
컵라면,1700,10,null

promotion.md 파일

name,buy,get,start_date,end_date
탄산2+1,2,1,2024-01-01,2024-12-31
MD추천상품,1,1,2024-01-01,2024-12-31
반짝할인,1,1,2024-11-01,2024-11-30

-> 이렇게 2가지 파일이 주어졌다.

products 안에 있는 내용은 저 형식대로 그대로 보여주어야하고, 마지막에 존재하는 promotion 값을 promotion.md 파일과 연결을 해야한다.

그래서 나는 각각의 파일 첫줄에 있는 key 값들로 객체를 만들고, 이것들을 배열로 묶는 방식으로 파싱을 하려했다.

1. 파일 불러오기

우선, 마크다운 파일을 파싱하고자 하는 파일로 불러와야한다. 그러기 위해선 2가지 개념을 알아야한다.

fs : 파일 시스템을 다루기 위한 Node.js 내장 모듈로, 파일을 읽고 쓰거나, 생성, 삭제하는 작업 수행 가능

path : 파일 경로를 다루기 위한 Node.js 내장 모듈로, 운영체제의 경로 구분자를 자동으로 처리하며 경로를 합치고 분석하는 기능 제공

즉, fs는 파일 내부에 있는 내용을 읽거나 가공할 때 사용하기 위해 쓰는 모듈이고, path는 우리가 사용하는 "//" 이런 경로를 좀 더 확실하게 사용하기 위해 쓴다.

path 모듈 왜 사용해?
path 모듈을 사용하지 않고 단순히 경로를 문자열로 작성해도 코드가 동작할 수 있다. path 모듈을 사용하는 이유는 코드의 이식성과 안전성을 높이기 위해서이다.
운영체제 독립성
운영체제마다 경로 구분자가 다르다.
ex) Windows는 \를 경로 구분자로 사용, UNIX 기반 시스템(Linux, macOS)은 /를 사용

fs 사용법

import fs from "fs"

const filePath = "public/products.md"
const data = fs.readFileSync(filePath, "utf-8"); 
//filePath에 있는 파일이 UTF-8 인코딩으로 해석되어 JavaScript 문자열로 반환
console.log(data);
//{~~~}(products.md 내부에 있는 텍스트가 나오게 된다.)

path 사용법

import path from "path"

const filePath = path.join(process.cwd(), "afaf/hi.md");
//process.cwd() -> 현재 작업 디렉터리의 절대 경로를 반환
//ex) 코드가 /Users/hoyychoi/projects/my-app 디렉터리에서 실행 중이라면, process.cwd()는 이 경로를 반환

console.log(filePath);
// 'public/products.md' 경로에 앞에 절대 경로까지 붙여서 생성된다. ex) Users/hoyyChoi/projects/my-app/public/products.md

이제 fs, path 를 기반으로 마크다운 내부에 있는 text를 자바스크립트의 변수에 담았다. 이제 이것을 내가 원하는 형식으로 객체로 변경해 배열에 담는 작업을 진행한다.

2. 파일 내부 text 파싱해서 객체에 담기

  1. 우선 데이터의 형태를 보면 줄바꿈 처리 단위로 나눠져 있으므로, split 메소드를 이용해 구분한다.
  2. 첫번째 줄은 객체들의 key값으로 사용해야하기 때문에 header라는 이름으로 뺀다.
  3. 그리고 각 줄은 현재 ","로 구분되어 있으므로, 이것들도 split 메소드를 이용해 구분지어 준다.
  4. 구분지음과 동시에 해당 key에 맞는 value를 집어넣어준다.
  5. 이걸 map으로 돌려서 배열에 객체들을 넣어준다.
  • parsing 함수
function parseCSV(data) {
      const [headerLine, ...lines] = data
        .split("\n")
        .filter((line) => line.trim() !== "");

      const headers = headerLine.split(",").map((header) => header.trim());

      return lines.map((line) => {
        const values = line.split(",").map((value) => value.trim());
        return headers.reduce((obj, header, index) => {
          obj[header] = values[index] === "null" ? null : values[index];
          return obj;
        }, {});
      });
    }

3. 객체 출력하기

const filePath = path.join(process.cwd(), "public/products.md");
const data = fs.readFileSync(filePath, "utf-8"); 
const products = parseCSV(data);

console.log("Products:", products);
//Products: [{ name: '콜라', price: '1000', quantity: '10', promotion: '탄산2+1' }, { name: '콜라', price: '1000', quantity: '10', promotion: null }]

이렇게 하면 내가 원하는 형태의 객체로 출력이 가능하다.

결론

이렇게 작업을 하면 코드를 실행과 동시에 마크다운을 파싱해서 객체로 담게 되고, 객체들만 건드려서 상품들의 재고들을 건들일 예정이다!

그리고, 파일을 불러와서 읽고, 파싱을 하는 메소드들를 한 클래스로 담아 관리할 예정이다.!

profile
칼을 뽑았으면 무라도 썰자! (근데 아직 칼 안뽑음)

0개의 댓글