작동 되는 코드를 만드는 것은 쉽다, 하지만 나중에 작성한 코드를 고치는 것은 어렵다.
내가 작성한 코드를 보면서 '왜 이렇게 만들었지?', '이건 왜 이렇게 했을까?' 란 물음표들이 뜨게 되고 '다음부터는 이러지 말아야지'라고 생각하게 됩니다. 내가 나의 코드를 보는데 다른 사람이 본다면 얼마나 많은 물음표가 뜨게 될까요. 그래서 이번 포스팅에서는 그동안 다음엔 이러지말아야지 개선해온 저의 코딩스타일을 공유해보려고 합니다.
저는 주석을 적는걸 취향이라고 생각하지 않습니다. 주석은 미래의 나와 다른사람을 위한 매너고 생산성을 높일 수 있는 필수 코드입니다.
저는 예전에 lodash함수를 사용하는 것을 좋아했습니다. lodash를 사용하면 마법처럼 값이 내가 원하는대로 변형되는게 좋았습니다. 아래는 제가 1년전 쯤에 작성한 코드입니다.
import {intersection, pick, keys, pickBy} from "lodash";
const values = pick(object1, intersection(keys(draft), keys(object1)));
const notNullValues = pickBy(values, value => value !== null);
object1에서 draft와의 중복 속성만 가져와 null이 아닌 값만을 만들어주는 함수이다.
이것을 단 두줄로 해결하였다. 와우! 놀랍지 않나요?😱
지금 봐도 intersection은 뭔지 pick은 뭔지 pickBy는 뭔지 알수가 없다.
어떤 기능을 하는지 알기 위해서는 lodash문서에서 일일히 찾아서 파악을 하는수밖에....
이 코드를 보는 누군가(내)가 고통받지 않도록 주석을 적어 그러한 수고를 방지하여야 합니다.
지금은 lodash 사용을 잘 안하게 되었고, 모든 함수에 설명을 달고 있습니다.
*Better Comments라는 vscode 익스텐션을 사용하는데 이것을 사용하면 주석에 색상을 줄 수 있습니다.
최소한 이정도의 주석은 있어야 저런 코드를 분해해 보지 않고 기능을 파악 할 수 있다.
물론 이해하기 어려운 코드를 안쓰면 되잖아요?, 변수명을 잘 지으면 되잖아요?, 주석과 코드가 다를수 있자나요? 라고 할수 있지만
주석을 사용하지 않을때 보다 주석을 쓰기 시작한 후의 코드를 찾는 속도, 이해하는 속도, 팀원이 제 코드를 이해하는데 용이하였습니다.
한국인으로써 영어보다는 한글에 눈이갑니다. 한글로 작성된 주석만 보더라도 함수의 기능을 빠르게 파악하고 원하는 것을 찾기 쉽습니다. 마우스를 휙휙 내릴때 한글만 보고 원하는 기능을 쉽게 찾을 수 있습니다.
저는 스타일드 컴포넌트(styled-components)를 자주 사용하고 있는데요. 스타일드 컴포넌트 내부에는 html태그와 class명을 이용하여 스타일링을 하고 있습니다.
저는 그림과 같이 '컴포넌트-콘텐츠'로 클래스명을 지어 사용하고있습니다. 이렇게 길게 클래스명을 작성하게되었을때 다음과 같은 장점을 얻을 수 있었습니다.
1. 코드만보고도 어떤부분을 담당하는지 상상할 수 있습니다.
2. 디버깅시 클래스명을 복사하여 검색하면 원하는 코드위 위치를 빠르게 찾을 수 있습니다.
3. 스타일드 컴포넌트 대신 html 태그를 사용함으로써 시맨틱 태그(Semantic Tag)의 이점을 가져올 수 있습니다.
3항연산자를 사용하면 가독성이 좋은 코드를 만들 수 있습니다.
하지만 3항연산자를 중첩하게 된다면 이야기가 달라집니다.
a==b ? "a=b" : "a!=b"
a==b ? a==c ? "a=b,a=c" :"a=b,a!=c" : "a!=b"
2단중첩만 해도 헷갈리기 시작합니다. 그런데 리액트의 JSX문법에서는 다음과 같이 사용하게 되는데
<>
{a==b ? <Component1>
...
...
...
<div>
{a==c ? <Component2>
...
:<Component3> }
</div>
:
<Component4>}
</>
이것이 스크롤이 길어질수록 정말 보기 힘들어집니다.
그래서 저는 삼항연산자의 중첩을 사용하지 않습니다. 대신에 다음과 같이 사용하도록 하였습니다.
{a==b && <Component1>}
{a==b && a==c && <Component2>}
{a==b && a!==c && <Component3>}
{a!==b && a!==c && <Component4>}
삼항연산자 중첩대신 중복되어 보일지라도 직접적으로 보이는것이 만족도가 매우 높았습니다.
price라는 변수의 타입은 무엇일 것 같나요? 저의 생각은 number입니다.
그런데 프로그래밍을 하다보니 url에서 값을 받게되는 경우가 많았는데요. 이러한 경우 값의 타입은 string | string[] 였습니다.
그래서 과거에는 api를 보내거나 받을때 url로부터 값을받을때 전부 string으로 만들어서 사용하였습니다. 그런데 나중에 보게될 때 '이 값은 number일 것 같은데 왜 string일까?'라는 생각이 계속들게 됬습니다. 그 코드를 처음 본 사람도 왜 string일지 찾아보게될 것이라 생각했고, 결국 편할거라 생각하여 변형된 타입이 오히려 더 혼란을 주는 것 같아서. 단순하게 가는것이 제일 좋다고 생각하게 됬습니다. 그래서 변수의 타입은 바로 떠오르는 타입으로 사용하는것이 제일 만족도가 높았습니다.
css를 작성할때에 속성들의 순서를 균일하게 하고있습니다.
함수형 컴포넌트를 만들때 state-커스텀hooks-function-useEffect 처럼 구조를 정하여 사용하고 있습니다.
page폴더와 component의 구조를 동일하게 하여 관련 컴포넌트를 찾기 쉽도록 합니다.
아이콘의 저장 위치를 '페이지-컴포넌트-콘텐츠' 구조로 클래스명과 동일하게 저장합니다.
ex) 투두리스트 삭제아이콘 : public/static/svg/todo-list/todo/delete.svg
api, type 등을 카테고리로 분리합니다.
ex) api/user, api/todo
types/user, types/todo
스타일 정보는 스타일이 사용되는 곳에 있어야 합니다. 다른 파일에 있다면 찾기가 쉽지 않습니다.
.toto-list{}
...
<ul className="todo-list">
글의 처음에 작성한 것 처럼 작동 되는 코드를 만드는 것은 쉽다, 하지만 나중에 작성한 코드를 고치는 것은 어렵습니다. 계속해서 코드를 읽기 쉽고, 찾기 쉽고, 다른 사람(나)가 이해하기 쉽도록 작성하는법을 고안해보았고, 팀에서도 좋다고 생각되는 부분은 함께 사용되게 되었습니다. 저는 코딩스타일이 2-3개월마다 바뀐다고 생각할만큼 더 좋은 방법이 있다면 개선해나가고 있습니다. 만약 제 생각과 반대가되거나, 여러분만의 노하우가 있다면 댓글로 알려주신다면 알려주세요. 감사합니다 :)
도움 많이 됐습니다