const isDirectory = (dir) => {
if (fs.lstatSync(dir).isDirectory()) {
return true;
}
return false;
}
const pushFiles = (dir, file) => {
dir["files"] === undefined ? dir["files"] = [] : null;
dir["files"].push(file);
}
const getDirectoryStructure = (dir, folderStructure, prevFolder) => {
fs.readdirSync(dir).map((v,i) => {
const tempDir = path.join(dir, v);
folderStructure[prevFolder] === undefined ? folderStructure[prevFolder] = {} : null;
if (isDirectory(tempDir)) {
folderStructure[prevFolder][v] = {};
getDirectoryStructure(tempDir, folderStructure[prevFolder], v);
} else {
pushFiles(folderStructure[prevFolder], v);
}
});
}
저번 포스트의 지저분했던 test()
함수에서 위와같이 짧고 간단한 재귀함수인 getDirectoryStructure
로 다시 태어났다.
물론 이것보다 훨신 더 깔끔한 구조로 짤수 있을것같은 느낌이 드는데 현재 필자의 역량에선 이게 최선이다... 아쉬운점은 이정도로 하고 결과물은 잘 나오는지 확인해보자.
// result
{"posts":{"back":{"express":{},"node":{}},"devops":{"aws":{},"docker":{}},"front":{"next":{},"react":{"files":["2022-09-22#[React]_React_Hook_이란?.md","test.md"],"tt":{}},"files":["ts.md"]},"temp":{"files":["nblocking.md"]}}}
{
"posts":{
"back":{
"express":{
},
"node":{
}
},
"devops":{
"aws":{
},
"docker":{
}
},
"front":{
"next":{
},
"react":{
"files":[
"2022-09-22#[React]_React_Hook_이란?.md",
"test.md"
],
"tt":{
}
},
"files":[
"ts.md"
]
},
"temp":{
"files":[
"nblocking.md"
]
}
}
}
위와같이 비어있는 디렉토리도 나오게 되고 파일명들은 해당 디렉토리의 files 배열로 감싼것을 볼 수 있다. 이제 서버에서 넘겨준 디렉토리 트리로 메뉴화면을 만들어보자!
import React from "react";
import styled from "styled-components";
const Root = styled.div`
.menuTree {
}
`;
const getMenuTree = (value) => {
if (!value) {
return;
}
let keyArr = getKeyArr(value);
if (keyArr.length === 0) {
return;
}
return (
<div>
{
keyArr.map((v, i) => {
if (v !== "files") {
if (Object.keys(value[v]).length >= 1) {
return (
<div key={i}>
{v}
{getMenuTree(value[v])}
</div>
);
}
return <div key={i}>{v}</div>
} else {
return value[v].map((file, index) => {
return <div key={index}>{file}</div>
})
}
})
}
</div>
);
};
const getKeyArr = (value) => {
if (!value) {
return;
}
let keyArr = [];
for (let objKey in value) {
keyArr.push(objKey);
}
return keyArr;
}
const MenuTree = ({
value
}) => {
if(!value) {
return;
}
return (
<Root>
<div className="menuTree">
{
getMenuTree(value?.posts)
}
</div>
</Root>
);
};
export default MenuTree;
위 로직을 간단하게 설명하면 1차적으로 서버단에서 넘겨준 메뉴트리들의 키값을 가져온 후 해당 키값들을 재귀함수와 반복문을 통해 순차적으로 가져온다음 메뉴트리의 키값을 통해 디렉토리명과 파일명을 뿌려주게되는것이다. 메뉴 디자인은 다음 포스트에서 다뤄보도록 하겠다!
결과물 :::