{
    "componentChunkName": "component---src-pages-index-js",
    "path": "/",
    "result": {"data":{"site":{"siteMetadata":{"title":"irrationnelle","configs":{"countOfInitialPost":10}}},"allMarkdownRemark":{"edges":[{"node":{"excerpt":"intersection observer api 공식문서 를 참조하면 일반적으로 페이지 스크롤로 이미지나 다른 요소를 지연 평가로 불러오고 싶은 경우 무한 스크롤 페이지를 구현하고 싶은 경우 이런 경우들을 다루기 위해 사용한다고 한다. intersection observer api 를 사용할 때, 브라우저 뷰포트나 대상 element 를 일컫어 root 혹…","fields":{"slug":"/21-12-07-intersection-observer/"},"frontmatter":{"date":"December 12, 2021","title":"Custom hook 을 이용해서 intersection observer 재사용하기","category":"dev","draft":false}}},{"node":{"excerpt":"server side rendering (SSR) Single Page App 이 유행하는 최근에는 오히려 접하기 힘든 개념이 되었다. 과거에는 사용자가 웹페이지와 상호작용하기 위해서 서버 사이드 렌더링을 사용했다. 서버 사이드 렌더링을 간략히 설명하자면 다음과 같다. 사용자가 웹페이지에서 요청을 보내면, 서버가 요청에 적합한 연산을 마친 뒤 결과를 토대…","fields":{"slug":"/21-11-17-sever-side-rendering-next-js/"},"frontmatter":{"date":"November 17, 2021","title":"서버 사이드 렌더링에 대해","category":"dev","draft":false}}},{"node":{"excerpt":"들어가기 전 언어 차원에서 인터페이스라는 개념이 존재하지 않는 자바스크립트에서 어떻게 DI 를 적용하는지 알아보기 위해, 먼저 DI 가 무엇인지 다시 공부할 필요를 느꼈다. DI 에 대해 그 필요성과 방법에 대해 토비의 스프링만큼 자세히 설명한 책이 없지만, 자바라는 정적 컴파일 언어 기반으로 설명을 하기 때문에 다음을 기약하기로 했다. 로버트 마틴의 클…","fields":{"slug":"/21-11-15-single-reponsibilty-principle/"},"frontmatter":{"date":"November 15, 2021","title":"단일 책임 원칙에 대해","category":"dev","draft":false}}},{"node":{"excerpt":"수정(21.11.18): act 로 감싼 fireEvent 에 대해 예제 코드에서  를  로 감쌌는데,  는 내부에서 이미  를 호출한다고 한다. Documentation mismatch: fireEvent wrapped in act() 그래서 지금(21.11.18) 예시에 있던  호출을 모두 삭제한다. API 요청에 test double 사용하기 일반적…","fields":{"slug":"/21-11-09-msw-tutorial/"},"frontmatter":{"date":"November 10, 2021","title":"MSW 를 사용해서 실제 API 가 작동하는 것처럼 mocking 하기","category":"dev","draft":false}}},{"node":{"excerpt":"input element 에서 키입력값을 받아오는 방법 위의 방법으로는 키입력을 할 때마다 이벤트가 발생하지 않는다. 키입력마다 이벤트를 발생시키고 싶을 때는 아래처럼  이벤트에 이벤트 리스너를 설정한다. 위와 같이 이벤트 리스너를 설정한 뒤, 철자 하나 하나 입력이 아닌 지금까지 입력한 input 값을 사용하고 싶을 때는  를 사용한다. input 이벤…","fields":{"slug":"/21-11-09-vanilla-javascript-input-and-test/"},"frontmatter":{"date":"November 09, 2021","title":"vanilla javascript 로 키입력마다 input 이벤트 발생시키기 그리고 테스트","category":"dev","draft":false}}},{"node":{"excerpt":"tdd 로 react 앱을 만들다가 firebase 구현 단계까지 왔다. 로그인 버튼을 클릭했을 때 signIn 함수를 호출하는 것까지 테스트하고 있으나 signIn 함수 내부를 테스트 하는 것에 대하여 고민이 좀 있었다. signIn 내부 함수를 유닛 테스트로 다루는 것이 맞는지, 아니면 signIn 함수 내부를 내부 구현 단계로 보고 인터페이스 역할을…","fields":{"slug":"/21-10-29-firebase-emulator-test/"},"frontmatter":{"date":"October 29, 2021","title":"firebase 에뮬레이터로 테스트 코드 작성하기","category":"dev","draft":false}}},{"node":{"excerpt":"이벤트 루프 자바스크립트는 기본적으로 싱글스레드에서 작동한다. 그래서 콜스택에 처리할 연산 목록을 쌓아두어 차례차례 실행한다. 콜스택에 연산 목록과 별개로 브라우저 API 요청이 있으면, 우선순위 queue 에다가 보관해놓고 콜스택을 비운 뒤 각 queue 에서 이벤트 루프가 연산들을 가져간다. 이 queue 에는 task queue, microtask …","fields":{"slug":"/21-10-19-event-loop-raf/"},"frontmatter":{"date":"October 19, 2021","title":"event loop 와 requestAnimationFrame","category":"dev","draft":false}}},{"node":{"excerpt":"Context API 단점 context api 에서 상태값을 변경하면, provider 로 감싼 모든 자식 컴포넌트들이 리렌더링한다. 그래서 context api 를 상태관리 도구로 사용하면 각 자식 컴포넌트들이 리렌더링하지 않도록 방어할 필요가 있다. 결론적으로 context api 는 상태관리 도구로 사용하면 props drilling 을 회피한다는…","fields":{"slug":"/21-10-07-context-and-state-management/"},"frontmatter":{"date":"October 07, 2021","title":"React 에서 Context API 와 상태관리","category":"react","draft":false}}},{"node":{"excerpt":"다시, 테스트 코드는 왜 스펙인가 약 반년 전에 이런 글 을 작성한 적이 있다. 이번에도 다시 테스트 코드와 스펙에 대한 이야기를 하려고 한다. 저번 이야기와 비슷한 이야기지만, 더 중요한 이야기가 될 것 같다. iOS 에는 단축어라는 기능이 있다. 특정 상황에서 iOS 가 사용자 대신 미리하기로 했던 시나리오를 수행하는 기능이다. 예를 들어 음악앱을 사…","fields":{"slug":"/21-10-07-test-and-spec-again/"},"frontmatter":{"date":"October 07, 2021","title":"다시, 테스트 코드는 왜 스펙인가","category":"dev","draft":false}}},{"node":{"excerpt":"firebase 서버리스하면 다들 aws lambda 를 떠올리는 것 같지만, 나는 firebase 를 먼저 손에 꼽는다. 일단 나는 공식 문서의 불친절함과 직관성이 전혀 없는 대시보드 등으로 aws 서비스를 우호적으로 생각하지 않는다. 그래서 개인 프로젝트는 gcp 나 azure 를 시도해보려고 하는데, firebase 는 이중에서도 가장 접근성이 좋다…","fields":{"slug":"/21-08-29-firebase-auth-sign-in-with-google/"},"frontmatter":{"date":"August 29, 2021","title":"firebase auth 이용하여 google 로그인 구현","category":"firebase","draft":false}}},{"node":{"excerpt":"예전에 NEXT STEP 에서 진행하는 ATDD 수업을 들으면서 코드 리뷰를 받던 중, 매직 넘버의 사용을 최대한 줄여야 한다는 피드백을 받은 적이 있다. 당시에는 변수명을 붙여주지 않고 상수를 그대로 사용하는 것이 가독성을 해치며, 이후에 수정이 생기면 값을 일일히 접근해서 수정하는 게 문제라 생각했다. 그러다가 오늘 리팩토링할 것이 떠오르면서 매직 넘…","fields":{"slug":"/21-03-20-magic-number/"},"frontmatter":{"date":"March 20, 2021","title":"매직 넘버를 지양해야 하는 이유","category":"Dev","draft":false}}},{"node":{"excerpt":"테스트 코드는 왜 스펙인가 cypress 가 앞으로도 다중 접속을 허용할 계획이 없다고 하여 e2e 테스트를 playwright 와 jest 조합으로 변경했다. cypress 에서 익숙했던 selector 설정에서 다시 playwright 에서 지정한 selector 탐색 방법을 사용하다 보니 로컬 테스트를 통과시키는 과정도 꽤 험난했다. 이 과정에서 p…","fields":{"slug":"/21-02-03-test-spec-why-fail/"},"frontmatter":{"date":"February 03, 2021","title":"테스트 코드는 왜 스펙인가","category":"Dev","draft":false}}},{"node":{"excerpt":"Promise 실행과 평가 시점에 대하여 코드 리뷰를 하는 중에 다음과 같은 코드를 보았다. 나는   의 조건과 상관없이  를 실행하기 때문에  를 조건문보다 위로 이동시키는 게 어떠느냐고 리뷰했다. 답변은 그렇게 하면 항상  가 끝난 뒤  가 작동하기 때문에 시간적으로 손해라는 것이었다.   를 연이어서 두 번 사용하기 때문에 A+B 시간이나 B+A 시…","fields":{"slug":"/21-02-03-promise-call/"},"frontmatter":{"date":"February 03, 2021","title":"Promise 실행과 평가 시점에 대하여","category":"Dev","draft":false}}},{"node":{"excerpt":"Typecsript 를 사용하면서 transpile 을 하지 않고  를 사용 하는 경우,  에  을 추가했음에도  에러가 발생하는 경우가 있다. 이 때  에 다음과 같은 옵션을 추가한다. 이 옵션을 추가하면  를 사용할 때는  로 import / export 하는 방식을  방식으로 하도록 오버라이드 한다.","fields":{"slug":"/21-01-03-unavailable-import-on-typescript/"},"frontmatter":{"date":"January 03, 2021","title":"Typecript 에서 Cannot use import statement outside a module 에러 해결","category":"typescript","draft":false}}},{"node":{"excerpt":"배열을 받아서  메소드를 이용해서 동적 key 값을 가지는 오브젝트로 변환하려고 하면 타입 에러가 곧잘 뜬다.  메소드의 accumulator 뿐만 아니라 빈 오브젝트를 선언하고 반복문 내부에서 동적 key 를 부여할 때도 마찬가지. 결국  타입을 쓰거나  어노테이션을 쓰거나 해야하는데 둘 다 찝찝하다면  타입을 사용하자. hackkerrank 문제를 풀…","fields":{"slug":"/20-10-18-record-type-on-typescript/"},"frontmatter":{"date":"October 18, 2020","title":"Typecript 의 Record 타입","category":"typescript","draft":false}}},{"node":{"excerpt":"테스트 코드 역시 중복을 제거하여 가독성을 살리고 유지보수를 용이하게 해주는 것이 중요하다. 사실 테스트 코드는 작성하지 않아도 월급을 주지 않거나 잘리는 일은 없기 때문에 소홀히 하는 경향이 더 강하기 때문에 오히려 더더욱 접근성이 높여줄 필요가 있다. Cypress 에서 자주 사용하는 selector 가 있거나 일반적으로 적용하는 timeout 옵션이…","fields":{"slug":"/20-10-17-cypress-helper/"},"frontmatter":{"date":"October 17, 2020","title":"Typescript 환경에서 Cypress helper 함수 만들기","category":"e2e","draft":false}}},{"node":{"excerpt":"간단한 의문이지만 코드 리뷰 중 비구조화 할당을 사용해서 프로퍼티 변경하는 것을 보았다. 공간 복잡도 측면에서 상대적으로 메모리 사용이 널널해진 요즘은 immutable 한 변경, 아니 재할당을 곧잘 보는데 이런 식으로 오브젝트의 프로퍼티를 변경하는 것을 보니 원하는 것처럼 참조 변경이 이루어지는지 궁금해서 찾아보았다. 결론적으로 비구조화 할당을 이용하여…","fields":{"slug":"/20-10-06-destructuring-assignment/"},"frontmatter":{"date":"October 06, 2020","title":"비구조화 할당은 얕은 복사","category":"Dev","draft":false}}},{"node":{"excerpt":"오픈소스 컨트리뷰톤이란? 오픈소스 컨트리뷰톤은 OSS 에서 주관한 프로그램으로, 약 6주간 멘토 개발자님과 함께 오픈소스 프로젝트에 참여하여 오픈소스의 생태계를 직접 겪어보고 자신의 역량을 살려 해당 오픈소스에 기여(contribute)하는 것을 목표로 한다. 그래서 이름도 contribute 와 marathon 을 결합한 컨트리뷰톤이다. 지원하기 오픈소…","fields":{"slug":"/20-09-19-contributon-epilogue/"},"frontmatter":{"date":"September 19, 2020","title":"2020 오픈소스 컨트리뷰톤 Mocha 후기","category":"Dev","draft":false}}},{"node":{"excerpt":"react 에서 기본적으로 제공하는 전역 state 관리 도구이다. redux 에 비해 보일러 플레이트가 현저히 줄어들었다. 상태 관리 뿐만 아니라, 메모이제이션 지원 및 컴포넌트 의존성을 줄이기 위한 reselect 역할과 외부 부수효과를 비동기적으로 다루기 위한 redux saga 같은 redux 미들웨어 기능도 겸한다. 개념 정리 atom react…","fields":{"slug":"/20-07-27-recoil-opinion/"},"frontmatter":{"date":"July 27, 2020","title":"recoil 정리","category":"react","draft":false}}},{"node":{"excerpt":"TDD 와 BDD, 그리고 명세(spec)에 대하여 들어가기 전 얼마 전 드디어 실무에서도 TDD, 아니 정확히는 BDD 로 업무를 진행해보았다. TDD 와 BDD 를 구분할 정도로 대단한 안목은 커녕, 둘 다 겨우 겨우 배워나가는 수준이나 최근 겪은 것들을 통해 아는 것을 정리해보려고 한다. 어쨌든 명세가 가장 중요하다 현재 자신이 진행하는 것이 TDD…","fields":{"slug":"/20-07-16-test-and-spec/"},"frontmatter":{"date":"July 16, 2020","title":"TDD 와BDD, 그리고 명세(spec)에 대하여","category":"Devops","draft":false}}},{"node":{"excerpt":"Hello Docker 토이 프로젝트에 CI/CD 를 붙이다가 Docker 를 오랜만에 다시 만지게 되었다. 평소 TIL 리포에만 글을 남기다가 오랜만에 블로그를 작성하는데 형식이나 친절도는 TIL 와 거의 비슷할 것 같다. CRA 로 간단한 react 앱 만들기 Dockerize 프로젝트를 Docker 컨테이너에 담는 작업을 dockerize 라고들 하…","fields":{"slug":"/20-04-22-cra-dockerize/"},"frontmatter":{"date":"April 22, 2020","title":"CRA 앱 Dockerize 하기","category":"Devops","draft":false}}},{"node":{"excerpt":"사실 지난 번 메소드 이야기를 잠깐 한 것은 이번에 클래스에 대해서 이야기를 해보고 싶었기 때문인데, 막상 클래스에 대해 설명하려니 클래스와 인스턴스의 관계까지 다루어야 하고 이야기가 길어질 거 같아 이번에도 리스트 이야기를 해보겠다. 여담으로 나는 클래스를 이해하는데 1년이나 걸렸는데(…) 요즘은 이렇게 말하고 다닌다, 걍 함수까지 같이 넣어주는 구ㅈ……","fields":{"slug":"/19-12-18-list-value-control/"},"frontmatter":{"date":"December 18, 2019","title":"list comprehension 과 map","category":"Python","draft":false}}},{"node":{"excerpt":"얼마 전 스터디에서 개별 변수를 사용하지 않고 리스트를 굳이 왜 사용해야 하느냐는 질문을 받았다. Why should we use List? 곧 크리스마스 시즌이다. 크리스마스에 할 일도 만날 사람도 있는 Louie 는 이번 크리스마스는 좀 색다르게 지내고자 크리스마스 파티를 계획한다. 파티에 사람을 초대하기 위해 크리스마스에서 혼자서 궁상 떨만한 사람들…","fields":{"slug":"/19-12-16-list-comprehension/"},"frontmatter":{"date":"December 16, 2019","title":"list 이해하기","category":"Python","draft":false}}},{"node":{"excerpt":"개발을 공부하다보면 ‘문(statement)‘이라는 말을 많이 사용한다. 조건문 또는 if문, 반복문 또는 for문 이렇게. 그런데 가끔씩 ‘식(expression)’ 이라는 표현을 쓸 때도 있다. 람다식(lambda expression)이 그 중 하나이다. statement 와 expression 식과 문을 비교하는 좋은 글들이 많이 있기 때문에 여기서…","fields":{"slug":"/19-12-10-lambda-expression/"},"frontmatter":{"date":"December 10, 2019","title":"lambda expression","category":"Python","draft":false}}},{"node":{"excerpt":"소설 ‘폴라리스 랩소디’ 에는 다음과 같은 구절이 나온다. “정말 다 돌려줄 수 있을까요? 우리가 세상에서 받은 것을 다 돌려주려면 우리는 세상 전체를 볼 줄 알아야 해요.\n빵 한 조각을 들어올리며 농부와 수레꾼과 방앗간 일꾼과 제빵사와 … 아아, 이건 끝도 없어요.\n어쨌든 그 모든 것을 볼 수 있을까요?” 이 구절의 서사적 의미와 철학적 고찰에 대해서는…","fields":{"slug":"/19-12-09-why-use-return-statement/"},"frontmatter":{"date":"December 09, 2019","title":"return 을 사용하는 이유","category":"Python","draft":false}}},{"node":{"excerpt":"원래는  의 사용목적에 대해서 쓰고 있었으나 내용이 길어지고 여러가지 개념들이 혼재되는 것 같아서 네임스페이스 부분을 잘라내어 따로 포스팅한다.  에 대한 언급이 간간히 나오는데 수정하지 않고 냅둔 것은,  의 사용에 대해 어렴풋이 느끼고 생각해볼 수 있는 기회라고 여겨서이다. 네임스페이스 이해하 의자 바꾸기 함수에는  이 없었다. 하지만 함수를 호출하고…","fields":{"slug":"/19-12-08-namespace-and-scope/"},"frontmatter":{"date":"December 08, 2019","title":"네임스페이스와 함수","category":"Python","draft":false}}},{"node":{"excerpt":"의자 바꾸기 문제 개발자들 사이의 농담이 하나 있다. 개발자 두 명이 있을 때 서로 의자를 바꾸기 위해서는 의자가 3개가 필요하다는 것이다. 이른바 변수의 값을 서로 바꾸는  이라는 상황인데, 사람은 의자에서 일어나 규정되지 않은 공간 위에서 잠시 서있다가 다른 의자로 옮겨 갈 수 있지만 변수는 그게 안 된다. 변수 입장에서 규정되지 않은 공간이라는 건 …","fields":{"slug":"/19-11-29-iimmutable-and-mutable2/"},"frontmatter":{"date":"November 29, 2019","title":"의자 바꾸기로 생각하는 인자 전달","category":"Python","draft":false}}},{"node":{"excerpt":"개발 용어 사전이 필요해 처음 개발 공부를 하던 당시 만들고 싶었던 것이 있었으니 개발 용어를 설명해주는 위키였다. 지금이야 의존성 주입이니 제어의 역전이니 하는 말을 들어도 대충 어떤 개념인지 감을 잡고 다시 찾아보는 정도인데, 입문 시절 때는 용어 하나 하나를 이해하는 것이 정말 큰 스트레스였다. 또 비슷해 보이는데 다르게 부르는 것들도 제법 된다. …","fields":{"slug":"/19-11-27-call-by-value-refrence-deep-shallow-copy/"},"frontmatter":{"date":"November 28, 2019","title":"immutable 과 mutable","category":"Python","draft":false}}},{"node":{"excerpt":"왜 나는 이런 고민을 하게 되었나 개발을 하던 중에 모달 이벤트를 처리해야 하는 경우가 있다. 블로그에서 글을 삭제한다고 하자. 이 때 삭제 버튼을 누르자마자 바로 삭제를 수행하는 것은 조금 위험하다. 그러니 정말 삭제할 것인지 물어보는 모달을 띄운다. 해당 모달에서 삭제한다고 했을 때, 비로소 정말 삭제를 수행한다. 간단한 이벤트 처리이다. 모달을 범용…","fields":{"slug":"/19-04-25-rxjs-trigger/"},"frontmatter":{"date":"April 25, 2019","title":"RxJs를 이용하여 비동기 이벤트가 발생하면 버튼으로 제어하기","category":"RxJs","draft":false}}},{"node":{"excerpt":"이상과 현실 기술부채라는 말이 있다. 간단히 말하면, 프로젝트 마감날짜를 지키기 위해 구현 외의 모든 것을 미루는 행위다. 개인적으로는 테스트 케이스를 작성한다거나, 리팩토링을 한다거나 하는 부분에서 기술 부채를 민감하게 느끼는 편이다. 리팩토링의 경우 자잘한 리팩토링은 널리 알려진 방식처럼 하드코딩 후 중복제거 라는 방법으로 어느 정도는 하는 편이지만,…","fields":{"slug":"/19-04-22-trust-asset/"},"frontmatter":{"date":"April 22, 2019","title":"신뢰자본과 개발주도","category":"Dev","draft":false}}},{"node":{"excerpt":"AWS Lightsail AWS Lightsail 과거에는 digitalocean이나 vultr 같은 곳을 저렴한 비용으로 사용했지만, 한국에 리전까지 있고 월 $3.5 로 AWS 의 인프라를 경험할 수 있다는 점에서 Lightsail 을 사용하지 않을 이유가 없다. 막상 사용해보면 기존의 AWS 콘솔을 사용하지 않고 Lightsail 전용 대시보드가 나…","fields":{"slug":"/18-10-06-flask-gunicorn/"},"frontmatter":{"date":"October 06, 2018","title":"AWS Lightsail에 flask + gunicorn + nginx 조합으로 간단한 서버 만들기","category":"Python","draft":false}}}]}},"pageContext":{}},
    "staticQueryHashes": ["3128451518","3474900066"]}