우아한테크러닝 4차시가 끝났습니다.
저번에 이야기했던 Bold, Italic, Underline을 글자 드래그 했을 때 팝업 형태로 나타나는 것을 구현한 PR을 함께 살펴봤습니다.
그리고 지금까지 진행하던 방식의 한계를 느끼고 진행 방식을 함께 논의해 바꾸는 시간도 있었네요. 그 후에는 진행 방식 의견 중 하나였던 컴포넌트에 대한 깊은 논의를 해보았습니다.
아래는 제가 정리한 내용입니다!
설명한 걸 말로 설명하지 못 한다면 안다고 할 수 없을 것 같다
아니다, 알 수 있기도 한데 말을 잘 안 해봐서 설명할 수 없는 것 같기도 하다.
하지만 면접 같은 거 볼 때는 설명을 해야 하니까 연습 해야지
자기가 안다고 생각되는 걸 일단 글로 막 써보고
글로 쓴 걸 읽어보면 분명 이상할 테니
다시 고쳐보고 다시 읽어보고 다시 고쳐보고 하면서 단단하게 만들어야 한다.
마치 꿈같은 상태.
일어나서 무슨 꿈이었는지 적어보려 하면 뭔지 기억이 나는 것 같은데 써보려면 듬성듬성 하고
아는 게 이런 상태로, 머릿속에 정리가 안 된 상태로 흩어진 상태로 있는 걸 다시 조립하면서 연결 시키면서 개념을 정리하는 시간이 필요하다.
정리 후에는 발표 자료를 만들어보고 발표를 해보고
이렇게 하면 정리가 된다. 이렇게 하지 않으면 계속 아는 듯 모르는 듯한 상태로 남아있거나 아주 더디게 알아질 것이다.
본인이 알고 있는 걸 잘 정리해서 설명할 수 있으면 굉장한 경쟁력이 될 것
개발자가 개발만 잘 하면 됐지 문서도 잘 쓰고 해야 하나 ... → 이런 생각 노!
연차가 가면 갈수록 더 그런 것들이 많이 요구될 것. 이런 게 안 되면 역량이 의심받고 이런 게 있기 때문에 꼭 본인만의 방법으로 정리해서 얘기하고 설명할 수 있는 엔지니어가 되어야 한다고 생각합니다.
문제가 많아요.
뭘 샀는데 메뉴얼을 안 본 것과 같다.
메뉴얼을 보지 않는 건 '단순이용'을 하는 것이고
소프트웨어는 그렇지 않다. 만드는 어플리케이션이 단단했으면 좋겠고, 클린했으면 좋겠는 게 우리의 목적
그러기 위해서는 저작자의 의도를 파악해야 하고, 그 저작자의 의도는 공식문서에 있다. 그래서 공식문서는 여러 번 반드시 봐야 한다
Flux 패턴을 안 가지고 가다 보니까 에러 파악이 어렵고
mobx 5 버전 이하에서는 데코레이터를 사용하는데, 그게 공식이 아니다 보니 꺼려하는 경향
클래스로 쓰는 걸 꺼려하는 경향
국소적으로 적용하기에는 mobx가 더 유용한 거 같은 느낌
모백스는 자유도가 높은 느낌 → 리덕스처럼도 만들 수 있고, 앵귤러처럼도 만들 수 있고
개발하는 맛, 설계하는 맛이 있는 것 같다
미들웨어 개념. 함수인 액션도 받을 수 있다
async await 동작시키고 이후에 액션 받아서 동작시킬 수 있다
Dispatch => thunk 감지 => thunk 내에서 다른 action dispatch
function createThunkMiddleware(extraArgument) {
return ({ dispatch, getState }) => (next) => (action) => {
if (typeof action === 'function') {
return action(dispatch, getState, extraArgument);
}
return next(action);
};
}
const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;
export default thunk;
컴포넌트는 리액트에서만 쓰이는 게 아니라 다양한 분야에서 쓰이는 용어
Q. 리액트를 사용한지 8개월차인데, 고민이 되는 게 리액트의 철학은 공통적으로 어떤 걸 만들어놓고 다들 가져다 써라라고 하는데, 사실 사용하다 보면 페이지 안에서만 컴포넌트를 만들고 거기서만 쓰는 경우가 많아지는 것 같다. 어떻게 하면 철학을 잘 따라갈 수 있을까요? 그리고, 리액트의 디자인 패턴을 많이 봤는데, 함수형으로 짜는 걸 많이 봤고 클래스로는 안 해봤는데, containers라는 컴포넌트가 하나 있고 데이터를 뿌려주기만 하는 컴포넌트가 따로 있더라. 그게 뭔지 봤더니 동작을 다루는 건 컨테이너 안에 들어가있고, 동작을 다 한 걸 바탕으로 props로 전달을 해서 컴포넌트가 또 받는 이런 방식이 있는데 이 부분이 궁금합니다.
A. 컴포넌트가 다들 뭐라고 생각하세요? UI의 최소 단위, 재사용성의 단위, 역할의 위임 등등 .. 리액트를 가지고 일반적인 어플리케이션을 만드는 방식으로 만들면 걔는 컴포넌트가 아니라고 생각. 컴포넌트가 아니기 때문에 재활용이 일어나지 않는 것. 사실상 리액트로 만드는 jsx를 감싸는 컴포넌트라고 하는 건 버추얼돔에 불과하다고 생각하고, 그 앱 안에서 재활용 되는 컴포넌트는 만들 수 있다. 버튼, 메뉴 등등. 말은 컴포넌트인데, 사실은 그게 컴포넌트가 아니기 때문에 자연스레 그런 고민이 되는 것 같습니다. 컴포넌트가 아니라면 그건 뭐지? 진짜 컴포넌트는 뭐지? 라는 질문을 가지게 될 거 같은데, 컴포넌트라는 건 그 자체로 완전한 독립성을 가지고 있어야 한다. 그래야 재활용이 가능하기 때문에. 그러나 그 컴포넌트가 그렇게까지 재활용, 재사용이 되기 위해서는 리액트에서 얘기하는 컴포넌트의 속성이 부족하다. 데이터 처리도 해야 하고, 다양한 걸 해야 하고 이게 독립적이어야 하는데, 리덕스 같은 거라도 붙이는 순간 독립적이지 않음. 그러면 컴포넌트가 될 수 없다. 리액트도 그래서 그런 식의 컴포넌트라는 용어를 쓰긴 하지만 완전히 독립된 컴포넌트끼리 더 큰 컴포넌트를 만들 수 있는 프레임워크를 제공해야 하는데, 리액트는 그걸 전혀 제공하고 있지 않기에 굉장히 까다로운 부분들이 있다. 진짜 컴포넌트가 되려면 HTML 진영의 웹 컴포넌트 표준이 있다.
https://developer.mozilla.org/en-US/docs/Web/Web_Components
웹 컴포넌트가 진정한 컴포넌트라는 얘기를 하고 싶은 건 아니고 웹 컴포넌트가 다루고 있는 기술 셋의 구성들을 보면 컴포넌트가 되려면 독립된 개체로서 작은 모듈이 되려면 어떤 기술셋과 어떤 스펙을 지원해야 하는구나, 어떤 게 필요하구나를 감을 잡을 수 있을 것. custom element, shadow dom, HTML template을 사용해 만드는 방법을 제공하고 있음. 이걸 보다가 리액트나 vue.js의 컴포넌트를 보면 이상해 보일 것. 하지만 개발자들이 이걸 안 쓰는 이유는 이게 굉장히 고민할 게 많기 때문이다. 재활용성이 큰 함수를 만들수록 고민할 게 많은 것처럼. 장기적인 라이프사이클을 가지고 어느 정도의 호환성을 가지고 있어야 하냐를 고민해야 하기 때문에. 웹 컴포넌트가 다루는 기술셋도 넓고 고민해야 할 것도 많으니 귀찮고 싫은 것. 그래서 망해가고 있지 않을까.
우리가 만든 컴포넌트는 dependency 덩어리인데 떼서 다른 데 갖다 붙일 수 있겠어요? 재활용이 가능할까요? 어려울 거란 말이죠. 그냥 그러니 어느 정도의 dependency를 갖고 중복되는 걸 만드는 걸 허용하는 분위기인 거죠.
bluePrint → 타입스크립트 기반 UI를 제공하는 프레임워크 → 이걸 보면 리액트를 가지고 컴포넌트를 만들 수도 있겠구나 하는 생각을 하게 될 것 (코어를 바탕으로 확장하는 객체지향 구조를 가지고 있음), 그러나 일반 서비스를 만들 때 이만큼 고려하는 건 너무 스트레스가 될 것. 그니까 그냥 진짜 '컴포넌트'가 아니라고 생각하고 UI의 최소 조각 정도로 가볍게 생각했으면 좋겠다. 애초에 리액트가 그런 걸 잘 할 수 있게 만들어지지 않았으니까.
반대로 atomic design pattern도 있죠. 가장 최소 단위의 컴포넌트를 만들고 조금씩 큰 규모의 컴포넌트를 만드는 방식으로 앱을 만들자 하는 디자인 패턴 → 이렇게 하면 컴포넌트가 될 수 있겠다, 하지만 개념만 가져오고 서비스 단위에서만 적용하다 보니 약간 부족한 느낌. 단일 서비스를 벗어나 여러 서비스에 적용이 되려면 쉽지 않을 겁니다.
컴포넌트를 완벽하게 만들어서 낼 것이냐, 현실을 인정하고 서비스에서 편하게 쓰이는 작은 조각을 잘 구성할 것이냐에 따라 방향성이 달라질 것이다. 두 가지 방법이 있을 것.
Q. 제가 처음 컴포넌트 설계를 이야기했는데, 진짜 컴포넌트적인 것을 만든다기 보다는 UI 렌더링 단위의 React 컴포넌트 설계를 이야기 한거 였습니다. atomic 단위를 어떻게 하는건지 궁금했습니다!
A. 그게 결국에는 합의해야하는 기준일 것.
Q. 재사용되지 않는 요소라도 가독성을 위해 (한 파일/컴포넌트의 코드가 너무 길어지지 않게) 컴포넌트화하는 것은 어떻게 생각하시나요?
A. 코드가 어쩔 수 없이 길어지는 경우가 있잖아요. 분리될 수 있는 단위라면 당연히 분리를 해야 하는 게 맞겠죠. 코드가 어떤 성격으로 되어 있느냐에 따라 분리 해야 하나에 대한 고민을 해봐야 할 것 같다. 일반적으로 어떻게 해라라는 건 유용한 답변이 아닌 것 같다.
Q. (토스 레퍼런스) 버튼 같은 데에서 로그를 써야 할 때 버튼 위에 다른 컴포넌트를 만들고 버튼을 감싸서 로그를 전송하게끔 하는 방법?
A. 그것도 좋은 방법인 것 같아요. 어떤 컴포넌트가 로그를 쏴야 하는지 모를 수 있다. 개별 컴포넌트가 로그 로직을 갖고 있다면 모든 컴포넌트가 로그를 쏠 수 있도록 준비해야 해 말이 안 될 거 같고, 컴포넌트를 로그 컴포넌트로 감싸고, 표준화된 이벤트들만 발행하고 감싼 컴포넌트들에 어떤 상황에 로그를 쏴야하는지만 주입시켜 놓으면 작동이 가능하니까 그 패턴은 좋은 설계인 것 같다.
많이 쓰이는 디자인 패턴 중에 하난데, 각각의 어플리케이션 상태를 외부에서 모니터링을 하고 싶을 때, 방법이 없잖아요. 그럴 때 운영체제에서 프로토콜을 만들어서 내부의 어떤 상황이나 동작이 생기면 외부로 어떤 메세지를 전송해야 해라는 규격을 만들어 놓으면 무조건 전송하게 되고, 바깥에서는 필요에 따라 그걸 받으면 사용이 가능해짐. Pub-sub(publish subscribe) 패턴처럼. 신문 발행을 막 하면 듣고 싶은 사람만 듣게 하는.
컴포넌트에 대한 다양한 시각들에 대해 살펴보는 시간을 가져보겠습니다.
스타트업의 꽃 피봇을 했습니다.
1. 배민에서는 라이브러리가 새로 나오면 바로 업데이트 하시나요 아니면 시간 텀을 좀 두시나요?
→ 아무래도 메인 앱에는 조금 보수적인 편이라 새로운 라이브러리나 업그레이드 버전이 바로바로 나오기보다는 테스트를 많이 거친다. 하지만 그게 아닐 경우 적극적으로 반영하기도 하고, 서비스마다 조금씩 다른 것 같다.
2. 버전업 소식은 보통 어디서 들으시나요?
→ 내부 소식통을 통해 듣기도 하고 외부 해커뉴스를 통해 듣기도 합니다.
3. 배민에서 어떤 프로젝트는 mobx를 쓰고 어떤 프로젝트는 redux를 쓰신다고 했는데, 사용하는 상태관리 라이브러리가 달라지는 이유가 있나요?
→ 한 팀에 있을 때도 둘 각각을 쓰는 팀들이 있었는데, mobx를 쓰고 싶다 하는 사람들이 많아 쓰기 시작했고 (엔지니어가 항상 그런 쪽에 갈증이 있다 보니 그런 쪽도 충족 돼야 한다고 생각) 리덕스가 단단하다 보니 설계가 재미가 없고, 할 게 많이 없다. 주니어개발자들도 설계 능력이 많이 늘어야 하는데 그걸 할 수 있는 기회가 많이 없어 mobx를 도입한 프로젝트들도 있고. 그러다 보니 두 개가 동시에 존재하는 구조가 된 것 같다.
4. 마인드맵으로는 회고를 안해봐서 그런데, 마인드맵으로 할 때도 정리가 잘 되셨나요? 블로그 글 쓰기 vs 마인드맵 개인적으로 어떤게 좋은가요?
→ 블로그는 안 하는데 위키(개인적으로 보는 블로그)를 쓰고 있고 마인드맵은 활용하고 있는데, 장단점이 있는 것 같다. 마인드맵은 컨텍스트를 하나 만들어 놓고 그걸 유지하면서 계속 늘려가는 게 재밌는 것 같다. 웹 어셈블리를 공부하면서 정리한 마인드맵. 책을 볼 때도 그렇게 많이 하는데, 마인드맵으로는 정리가 편하고 어딜 들어갔다가 다시 들어갔던 최초 지점으로 가기가 좋아서 마인드맵을 많이 씁니다. (툴: 엑스마인드)
5. 보통 인터뷰는 CS 지식이 탄탄해야된다고 하는데, 어떻게 공부하는게 좋을까요?
→ CS라는 것의 범위가 너무 넓다 보니까.. 애매하긴 한데, 볼륨이 있는 회사들일수록 기본기라고 생각하는 부분들에 대한 질문을 많이 하는 것 같고, 그렇지 않은 회사들의 경우에는 즉시 업무에 투입이 가능한지를 보는 질문들을 많이 하는 것 같다. 여기서부터 주니어에게 요구하는 소양이 조금씩 달라진다. 탄탄하다는 것도 정도가 모호하다 보니.. 제 기준에서 정의해보자면, 학교에서 배우는 컴퓨터 시스템에 대한 이해 정도에서 분야(백엔드, 프론트엔드)에 잘 버무려져서 이해하고 있는가를 보는 것 같다. 예를 들면 프로세스, 스레드, 메모리, 파일 시스템, 네트워크 이런 것들이 중요한 내용들인데, 이런 것들이 프론트엔드로 보면 어디에 접목돼? 브라우저가 자바스크립트 엔진이 싱글 스레드라고 하는데, 이게 운영체제로 연결이 되고, 프로세스를 관리하는, 스레드로 관리되는 대략적인 내용과 개념을 이해하고 있다면 브라우저라면 브라우저 안에 있는 프로세스들을 어떻게 관리해야겠구나 정도의 이해가 가능해진다. 그렇게 이해를 하고 있는지, 단지 그냥 자바스크립트는 싱글스레드래요 이렇게 주입돼서 외우고 있는지를 포인트로 해서 보는 것 같다. 이런 맥락에서 학습 전략으로 짜보면 어떨까 생각합니다. 사실 면접관마다 케바케긴 합니다.
6. 면접 인터뷰에서 신입의 경우에는 무엇을 중요하게 보시고, 경력의 경우에는 어떤 것을 중요하게 보시나요?
→ 신입의 경우에는 잘 성장할 수 있는가, 개발을 정말 좋아하는가를 본다. 잘 성장할 수 있는가는 기초가 잘 되어있고 기초가 잘 되어있는지를 보고 판단할 수밖에 없다. 이 정도 기초가 되어 있으니 이걸 바탕으로 이렇게 성장하겠구나. 심지어 이걸 좋아해? 그럼 빠르게 성장하겠구나를 보는 것 같다. 경력의 경우에는 그 경력에 준하는 일들을 잘 성장하면서 했는지를 본다. 5-10년차의 경우에는 리더십이라든지 문제를 풀어내는 능력을 많이 보는 것 같습니다.
7. Server side rendering, Client side rendering에 대한 민태님이 생각하는 장단점(?) 선택 기준(?)이 궁금합니다.
→ 장단점이랄 게 있나요? 이 질문을 듣고 생각나는 부분은 ,기본적으로 기술 그 자체로 장점과 단점이 있는 경우가 있지만, 서버사이드 렌더링과 클라이언트 사이드 렌더링은 기술이라기보다는 구성방식이라 저게 구현하는 서비스라고 하는 구체적인 형상이 없는 상태에서 두 가지 방식의 장단점을 논하는 건 의미가 없다는 생각이 든다. 서비스에 따라 각각이 쓰여야 할 상황이 다르다. 일반적인 얘기를 하자면, 서버 사이드 렌더링은 아키텍쳐 적으로 비용이 많이 들고 SEO 같은 거에서는 좋고, 초기 렌더링 타임이 사용자한테 전달되는 시간은 빠르니까 장점이 있고, 클라이언트 사이드 렌더링은 그 반대. 컴퓨팅 파워는 아예 안 들고, SEO 같은 거는 대응하기 힘들고, 대응한다 해도 복잡하고, 빠르지 않다는 점.
옛날에는 전부 다 서버 사이드 렌더링이었다. 자바스크립트가 빨라지고, 여러가지 것들이 가능해졌고, 서버 상에 클라이언트 코드가 묶여있고, 코드 상 유연성이 떨어지고 하면서 이게 좋아보였고, 클라이언트가 상태를 가질 수 있게 되니 사용자의 state를 훨씬 광범위하게 사용할 수 있게 되니 어플리케이션이 다양해졌고, 전부 다 앞뒤 않가리고 SPA(Single page Application)로 다 개발하는 분위기가 조성되었었다. 그러다 리액트 같은 프레임워크가 큰 역할을 해 (돔을 직접 다루는 게 아닌 추상계층을 다시 만드는 이런 방식) 중간층이 생기니 활용 범위, 유연성이 훨씬 늘어났다. 구현하는 사람 입장에서는 가장 최적화된 방법을 찾게 되었다.
8. 지난 기수 강의 중에 '이건 하길 잘했다', '이 강의의 반응이 제일 좋았다' 하는 강의가 있으신가요?
→ 리액트 만들어보기 (훅 정도까지, 왜 그렇게 생길 수밖에 없었는지 이해), 리덕스 미들웨더 공식문서 읽는 방법 강의