ziglog

    Search by

    6월 3주차 기록

    June 18, 2022 • ☕️☕️ 8 min read

    보란듯이 무너졌어… IE


    배워가기

    리버스 프록시

    포워드 프록시의 반대 개념이다. 앱 서버의 앞에 위치하여 클라이언트가 서버를 요청할 때 리버스 프록시를 호출하고, 리버스 프록시가 서버로부터 응답을 전달받아 다시 클라이언트에게 전송하는 역할을 한다.

    클라이언트는 애플리케이션 서버를 직접 호출하는 것이 아니라, 프록시 서버를 통해 호출하기 때문에 리버스 프록시는 애플리케이션 서버를 감추는 역할을 하게 된다.

    리버스 프록시 뒤에 여러 개의 WAS를 두어서 사용자 요청을 분산할 수 있으며(로드밸런싱), 보안 상의 이유로 서버에 직접 접근하는 것을 막기 위해 DMZ같은 네트워크에 리버스 프록시를 구성하여 접근하도록 할 수 있다.

    리버스 프록시의 예시로는 nginx, apache web server 등이 있다.

    Ref https://sujinhope.github.io/2021/06/13/Network-프록시(Proxy)란,-Forward-Proxy와-Reverse-Proxy.html

    노드 모듈 해석 전략

    • 상대경로일 때 (’/’, ’./’, ‘../’ 세 가지 경우)
      • 생각하는 것처럼 찾는다.
    • 절대경로일 때
      • package/src/node_modules 에서 찾는다
      • 없으면 package/node_modules에서 찾늗다.
      • 없으면 node_modules 찾는다.
      • 최상위까지 가서 찾아도 없으면 없다고 한다.

    리액트 컴포넌트의 state

    리액트에서 state를 자식 컴포넌트가 아닌 부모 컴포넌트로 끌어올려 저장하고 자식 컴포넌트는 제어 컴포넌트로 만들어주는 것이 좋다.

    부모가 자식컴포넌트의 state 를 요청하는 방식은 버그에 취약하며 리팩토링이 어렵기 때문이다. 또한 state 정의를 부모 컴포넌트에 할 경우 추후 자식 컴포넌트가 1개에서 여러 개로 늘어났을 때에도 자식 컴포넌트 간에 통신이 쉬워지고 부모 컴포넌트와의 동기화가 용이하다.

    cypress에서 api intercept하기

    cypress에서 api를 intercept하여 alias를 부여하고, 해당 alias에 wait를 걸면 api call을 기다릴 수 있다.

    이때 wait에 배열 형식으로 alias를 넣으면 여러 개의 api call을 기다릴 수 있다.

    Copy
    cy.intercept("/api/...").as("card-attributes");
    
    cy.wait("@card-attributes");
    // 배열 : cy.wait(['@alias1', '@alias2', ...]);

    cypress clock

    cypress의 clock 기능을 통해 setTimeout, setInterval 등 시간과 관련된 함수에 대한 제어권을 cypress로 넘길 수 있다.

    Copy
    let seconds = 0;
    
    setInterval(() => {
      $("#seconds-elapsed").text(++seconds + " seconds");
    }, 1000);
    // test.ts
    cy.clock();
    cy.visit("/index.html");
    cy.tick(1000);
    cy.get("#seconds-elapsed").should("have.text", "1 seconds");
    cy.tick(1000);
    cy.get("#seconds-elapsed").should("have.text", "2 seconds");

    jest에서도 시간 관련 함수를 mocking하는 기능을 제공한다. jest.useFakeTimers()로 사용할 수 있다.

    Ref https://docs.cypress.io/api/commands/clock https://jestjs.io/docs/timer-mocks

    객체 key에서 특정 prefix만 골라내기

    keyof typeof을 사용하여 객체의 key만 골라낸 후, 그중에서 특정한 prefix를 가진 key만 다시 추출해보자.

    Copy
    const colorTheme = {
      bg_primary: "blue",
      bg_secondary: "red",
      fill_primary: "blue",
      fill_secondary: "red",
    };
    
    type ColorKey = keyof typeof colorTheme;
    type BgIncluded = `bg_${string}`;
    type BgKeys = Extract<ColorKey, BgIncluded>;
    
    const bg1: BgKeys = "bg_primary";
    const bg2: BgKeys = "fill_primary"; // 🚨 Type '"fill_primary"' is not assignable to type 'BgKeys'.

    객체의 key들에서 특정 prefix만 골라내고, 해당 prefix를 제거할 수도 있다.

    Copy
    type Replace<
      T extends string,
      S extends string,
      D extends string,
      A extends string = ""
    > = T extends `${infer L}${S}${infer R}`
      ? Replace<R, S, D, `${A}${L}${D}`>
      : `${A}${T}`;
    
    interface ColorSet {
      fill_primary: string;
      fill_secondary: string;
      fill_accent: string;
      bg_accent: string;
    }
    
    type Color = keyof ColorSet;
    type ColorAsset = Extract<Color, `fill_${string}`>; // fill_primary | fill_secondary | fill_accent
    type Result = Replace<ColorAsset, `fill_`, "">; // primary | secondary | accent

    as const vs readonly

    객체를 as const로 선언해주면, 객체의 모든 프로퍼티가 readonly로 바뀌게 된다.

    Copy
    const color = {
      white: "#FFFFFF",
      blue: "#0000FF",
      red: "#FF0000",
    } as const;
    
    color.white = "#000000"; // 🚨 Cannot assign to 'white' because it is a read-only property.

    readonly는 타입이나 인터페이스에 사용한다.

    Copy
    type Color = {
      readonly white: string;
      readonly blue: string;
      readonly red: string;
    };
    
    const color: Color = { white: "#FFFFFF", blue: "#0000FF", red: "#FF0000" };
    color.red = "red"; // 🚨 Cannot assign to 'red' because it is a read-only property.

    만약 일부 타입의 속성들만 상수로 만들고 싶다면 해당 타입의 변수에만 readonly를 붙여주면 된다.

    JSX.Element props

    render props를 사용해 composition 형태로 props를 통해 컴포넌트를 주입받을 때, 컴포넌트의 props에 접근할 수 있다.

    prop으로 주입받는 타입을 JSX.Element로 선언하면 props와 type에 접근할 수 있다. 예를 들어, badge.type.displayName으로 접근하면 컴포넌트의 이름을 알 수 있다.

    Copy
    interface ButtonProps {
      badge?: JSX.Element;
    }
    
    const Button = ({ badge }) => {
      const size = badge.props.size;
      return <Button>{badge}</Button>;
    };
    
    <Button badge={<Badge size={14} />} />;

    window.location.href vs history.push

    • window.location.href

      • 새로운 HTTP call을 만든다 (새로고침 O)
      • 앱 상태 유지 불가
    • history.push

      • 새로운 HTTP call을 만들지 않는다 (새로고침 X)
      • 앱 상태 유지
    • 💡 window.open - target = ‘_blank’처럼 동작한다


    이것저것

    • CORS에러를 뚫어주는 Allow CORS extenstion은 서버로부터 응답을 받아 Access-Control-Allow-Origin: * 헤더를 추가해 다시 클라이언트에게 전송한다.
    • React.Children.toArray() 함수는 children을 1차원 배열로 평탄화해서 리턴해준다. 1차원 배열로 변환하는 과정에서 Reconciliation, 렌더링 최적화를 위한 고유한 key 값을 각 요소의 키에 삽입해준다.
    • 지면을 꾸미기 위해 사용된 이미지는 alt text를 빈 스트링으로 처리한다.

    기타

    Zero Trust

    제로 트러스트(Zero Trust)는 ‘아무것도 신뢰하지 않는다’는 것을 전제로 한 사이버 보안 모델로, 사용자나 기기가 접근을 요청할 때 철저한 검증을 실시하고, 검증이 이뤄진 후에도 최소한의 신뢰만 부여해 접근을 허용하는 방식이다.

    ZTNA (Zero Trust Network Access)는 ‘초세분화 적응형 인증 및 컨텍스트(Context) 인식 정책’으로, 원격 위치 또는 단말기에 클라우드 혹은 기업 데이터 센터에서 호스팅 되는 프라이빗 애플리케이션을 안전하게 제공하는 방법이다.

    기업은 주로 아래 4가지 중 하나를 해결하기 위해 ZTNA를 도입한다.

    1. 관리가 어려운 VPN 대체
    2. 멀티클라우드에 안전하게 액세스
    3. 외부사용자가 초래할 수 있는 위험 감소
    4. M&A 통합 가속화

    Ref https://www.lgcns.com/blog/cns-tech/31963/?fbclid=IwAR0KT_wT4y13yGyluc2s_xB7S1di1ysFKIjWrsc7Php2ehPOfQSBcEr2HhQ

    Reactathon

    정말 별별 ‘-톤’이 나온다! ‘The third age of JavaScript’를 주제로 한 이 영상은 자바스크립트 연대기를 3단계로 나누어 빠르게 훑어준다. 자바스크립트 언어 자체, 빌드 툴, 프레임워크, 런타임의 지나온 역사까지 소개하고 있다.

    TLDR; 정리하자면

    • 첫 번째 시기: 언어를 설계해나갔다.
    • 두 번째 시기: 사용자들이 언어를 확장해나갔다.
    • 세 번째 시기:
      • 레거시를 제거했다.
      • 여러 툴의 레이어를 무너뜨렸다.

    결과적으로, 더 좋은 DX와 UX가 탄생했다고 한다.

    • DX: 빠른 빌드, 산업 표준 툴
    • UX: 작은 번들, 빠른 배포

    Ref https://www.youtube.com/watch?v=CGnlBU3K_eM

    IE 지원 종료

    2022년 6월 15일 수요일… 역사적인 날이다!

    01

    Ref https://docs.microsoft.com/en-us/lifecycle/products/internet-explorer-11

    앱과 웹뷰 간 통신에 protobuf 사용하기

    네이티브 앱 안에서 웹뷰를 돌리면 제한된 기능 때문에 필연적으로 네이티브 앱과 통신할 일이 생긴다. 이때 양방향 통신이 안되는 불편이 있고, 만들때마다 일관성 없는 인터페이스가 생겨나기도 한다.

    Riid에서 앱과 웹뷰 사이 통신에 protobuf를 이용해서 서비스 인터페이스를 정의하는 방식을 소개하고 있다.

    Ref https://twitter.com/disjukr/status/1537034296959315968


    마무리

    IE 지원이 공식적으로 종료됐다! 🥳 그날이 오긴 왔구나… 시간 참 빠르다. 이제 더 이상 프론트엔드 개발자가 크로스브라우징 이슈로 골머리 썩히는 일이 없으면 좋겠다.

    싸이 흠뻑쇼 예매에 성공했다! 코로나 3년 만의 원기옥이 모여 정말 역대급 티켓팅이 아니었나 싶다… 오픈 3시간 만에 잡았는데도 서울 좌석이 절반 넘게 남아있었다. 인터파크 도라이 놈들… 사실 내가 아닌 동생이 성공해줬다. 후후후… 다쥬겄다.

    주 1회 출근하는 게 점점 익숙해져 간다. 하루 나가는 날은 잡담 시간이 굉장히 많아진다. 4일 일하고 하루는 사내 개발자 분들과 잡담 떨고, 어느 정도 적당한 밸런스인 것 같다.


    Relative Posts:

    6월 4주차 기록

    June 25, 2022

    6월 2주차 기록

    June 11, 2022

    zigsong

    지그의 개발 블로그

    RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon