📜

2021년 8월, 새롭게 보고 배운 것들

태그
회고
최종 편집
Dec 30, 2022 2:30 AM
발행일
August 28, 2021

HTML, CSS

  • 언제부터인가 웹킷 브라우저에서 링크 클릭시 부자연스러운 푸른색 깜빡임이 생겨서 보기 싫었는데, 알고 보니 -webkit-tab-hightlight-color 속성 때문이었다. transparent로 지정하니 제거됐다.
  • image
  • <button /><form /> 안에 있어야만 클릭시 submit 이벤트가 발생하는 줄 알았는데, 알고 보니 form attribute를 사용하면 폼 바깥에 있어도 submit 이 가능했다. (문서)
  • The <form> element to associate the button with (its form owner). The value of this attribute must be the id of a <form> in the same document. (If this attribute is not set, the <button> is associated with its ancestor <form> element, if any.)
    This attribute lets you associate <button> elements to <form>s anywhere in the document, not just inside a <form>. It can also override an ancestor <form> element.

JS, REACT

  • 패키지 A가 B에 의존하고 B가 C에 의존하면, A는 C에 대한 transitive dependency를 가진다고 표현할 수 있으며, npm은 A가 dependencies 면 A의 모든 transitive dependencies를 설치하지만, devDependencies 면 B까지만 설치한다는 것을 알았다.
    • 이건 bytes 주간 뉴스레터에서 배운 건데, 웹 프론트엔드 분야에만도 수많은 뉴스레터가 있고, 보다 보면 하나씩 다 구독하고 싶어진다. 하지만 인풋만 잔뜩 있다고 내것이 되지 않는다는 걸 알기에 한두 개를 꾸준히 보는 방식을 택했다. 그렇게 구독하는 뉴스레터 중 상당히 유용하고 재밌게 읽고 있는 게 ui.dev 에서 운영하는 bytes.dev 뉴스레터다.
    • 특이하게도 과거에 발행한 내용을 웹을 통해 게시하지 않고 있어서 배운 걸 링크로 걸기가 불가능하다. 😥
  • iterator를 배열로 만들려면 Array.from 을 쓰면 된다.
    • URL의 모든 search string을 object로 만들어서 써야 했는데, URLSearchParams.entries가 괜찮아 보였다. 그런데 이게 array가 아닌 iterator를 반환하길래 이를 배열로 변경한 다음 Array.reduce로 오브젝트로 변환했다.
    • function toSearchObject(urlSearchParams: URLSearchParams) {
        return Array.from(urlSearchParams.entries()).reduce(
          (accumulator, current) => {
            const [key, value] = current;
            if (accumulator[key]) {
              accumulator[key].push(value);
            } else {
              accumulator[key] = [value];
            }
            return accumulator;
          },
          {} as Record<string, string[]>,
        );
      }
  • JS에서는 nullundefined 도 오브젝트의 key로 쓸 수 있다. 즉 이런 코드가 허용된다.
    1. const obj = {};
      obj[null] = 1;
      obj[undefined] = 2;
    2. 물론 nullundefined 는 JS 세계에서 primitive data type이므로 어찌보면 당연히 가능해야 하나 싶기도 하지만 아무튼 알고 나서는 놀랐다.
  • svg 파일을 import하는 컴포넌트를 테스트 코드에서 렌더링하려고 하니 테스트가 깨졌다. 우리는 CRA에서 기본 제공하는 jest를 이용해 테스트를 하고 있었고, jest에서 만들어주는 DOM이 svg를 렌더링해주지 못하는 이슈였다. jest-canvas-mock을 추가하여 해결했다.
  • 캐시노트에서는 내부적으로 CSS modules를 사용하는 디자인 시스템 컴포넌트로 웹페이지 렌더링을 하고 있는데, CSS order에 대한 문제를 3개나 겪었다(하나는 7월에 겪은 문제긴 하지만). 만났을 때는 진땀나는데 해결한 뒤에는 쉽게 까먹는 게 이런 트러블슈팅 기록이라서, 따로 정리하여 공유 예정이다.
    • 로컬 환경과 프로덕션 환경에서 CSS 스타일이 다르게 나오는 현상
    • 로컬 환경에서는 빌드가 되는데 프로덕션 환경에서는 "css conflicting order"라며 빌드가 안 되는 현상
    • 어떤 페이지를 먼저 들어가느냐에 따라 스타일이 달라지는 현상

그 외

  • HammerspoonAppleScript를 이용한 업무 자동화
    • 회사의 외부망 전용 VPN과 내부망 전용 VPN을 키보드 단축키 한 번으로 전환할 수 있게 했다. 재택근무할 때 아주 유용하게 썼다.
    • 애플스크립트는 전용 스크립트 편집기를 통해서만 수정할 수 있음을 알게 됐다.
    • 사내 위키에 작성된 가이드 문서를 퍼블릭 공개 버전으로 옮기는 중이다.
    • ⌨️(예제로 알아보는) AppleScript와 Hammerspoon을 이용한 반복업무 자동화
  • git은 폴더경로가 변경된 것을 어떻게 알 수 있을까?
    • git을 매일같이 쓰면서도 내부 구조에 대해서는 큰 관심이 없었는데 재미있게 읽었다.
    • insert newline at last 가 중요한지 알게 됐고, 왜 git blame 에서 보이는 diff가 일관적이지 않게 느껴졌는지도 알게 됐다.
    • 이걸 읽고 나니 diff 의 일관성(또는 history 추적)을 위해서는 파일 이름/경로 변경 작업과 파일 내용 변경 작업은 별도 커밋으로 하는 게 좋겠다는 생각을 했는데, 그러면 github의 풀 리퀘스트를 머지할 때 스쿼시 머지를 하면 안되겠다는 생각도 동시에 들었다. 아직 어떻게 하는게 더 좋겠다는 결론은 내지 못했다.
  • 딥링크, 디퍼드 딥링크, 다이나믹 딥링크, 원링크의 차이
    • 사내에서 딥링크 를 계속 쓰고 있었는데도, 딥링크가 구체적으로 어떻게 동작하는지 몰라서 찾아보다 보니 간결하게 정리된 글이 있어서 이해가 잘 됐다.
    • 이중에서도 특히 "디퍼드 딥링크", 즉 앱 미설치 유저가 앱 설치 후 우리가 원했던 링크로 이동하게 되는 건 동작원리가 궁금했는데, 팀 동료인 그로스 리드 Ray 님이 잘 설명해주셨다.
    • - 디퍼드 딥링크를 제공하는 서비스에는 firebase, branch.io, appsflyer 등이 있다. - 유저가 이들이 제공하는 "브릿지" 페이지에 접속하면, IP 와 스크린사이즈 등 여러가지 기기 정보를 서버에 저장해둔다. - 유저가 앱을 설치하면 앱에 넣어둔 위 서비스의 SDK를 통해 서버에 질의하여, 모종의 로직으로 n분 이내로 동일한 기기로 접근한 것이라고 판단하면 원래 접근하려고 했던 링크로 이동시켜 준다.