ziglog

    Search by

    1월 4주차 기록

    January 28, 2023 • ☕️☕️ 8 min read

    7일같은 3일


    배워가기

    vitest

    vitest는 vite를 위한 Unit Test Framework다.

    vitest는 기본적으로 watch mode 로 실행되고, CI환경에서는 run mode 로 실행된다.

    vitest는 비단 vite 뿐만 아니라 vite를 사용하지 않는 프로젝트에서도 Jest 등의 대안이 되는것을 목표로 개발되고 있다.

    병렬 스레드를 사용한 빠른 실행 속도가 장점이다.

    vite + typescript template

    vite + typescript template을 사용하면 tsconfig.json과 tsconfig.node.json 두 가지 파일이 생긴다. 구분되는 이유는 두 가지 런타임 환경(브라우저/Node)에 대응하기 위함이다.

    src 이하의 코드는 브라우저에서 동작하지만, vite 자체는 Node에서 동작하기 때문이다.

    Ref Why does Vite create two TypeScript config files: tsconfig.json and tsconfig.node.json? 참고

    구버전 next 템플릿 사용할 수 있을까?

    npx create-next-app@{old-version} 명령어를 사용하더라도 구버전의 next 템플릿을 다운로드할 수 없다. CLI가 next의 카나리아 브랜치에서 직접 코드를 다운로드/추출하기 때문이다

    따라서 어떤 버전을 입력하든 가장 최신 버전(의 canary)이 설치된다. 즉, CLI(create-next-app)의 버전은 사용하는 next의 버전과 관계없다.

    cf) next13은 react18을 쓰기 때문에, react17를 사용하는 next12 환경 구성은 직접 해야만 한다..

    카나리아 (canary) 소프트웨어 엔지니어링에서 카나리아(canary)는 시스템의 안정성/응답성을 테스트하기 위해 프로덕션에 배포되는 작고 덜 중요한 변경을 뜻한다. 이 용어는 광산에서 카나리아가 죽음으로써 공기중 독성을 판별하는 방식에서 유례되었다 (불쌍한 카나리아..)

    chrome storage

    chrome storage는 chrome extension 개발에서 사용자의 데이터와 상태를 지속하는 방법을 제공한다. Indexed DB, localStorage와 비슷하지만 chrome extension에 맞게 디자인되어있다.

    • 모든 익스텐션 컨텍스트(service worker와 content scripts 포함)는 Storage API에 접근할 수 있다.
    • JSON serialize가 가능한 값들은 객체 프로퍼티 형태로 저장된다.
    • Storage API는 대규모 읽기와 쓰기 동작을 비동기로 처리한다.
    • 사용자가 캐시와 브라우저 히스토리를 지워도 데이터는 남아있다.
    • 저장된 세팅은 incognito(프라이빗 모드)를 사용하더라도 남아있다.

    Storage API는 다음 네 가지 버킷(스토리지 존)으로 나뉜다.

    • storage.local: 데이터는 로컬에 저자되며, extension을 지우면 데이터가 사라진다.
    • storage.sync: 같은 유저가 로그인된 브라우저라면 브라우저끼리 데이터를 공유한다. 다른 컴퓨터에서 내 크롬아이디로 로그인할 때 북마크가 유지되는 것과 같다.
    • storage.session: 브라우저 세션 기간 동안 메모리를 유지한다.
    • storage.managed: readonly 영역으로, 관리자가 세팅할 스키마를 통해 수 있다.

    Ref https://developer.chrome.com/docs/extensions/reference/storage/

    cSS1 vs cSS2 vs cSS3

    • CSS1 - 텍스트 서식, 폰트 설정, 마진 설정이 포함되어있다.
    • CSS2 - 요소의 위치(position)를 공식으로 포함한다.
    • CSS3 - 반응형 디자인을 지원하며, 여러 속성(gradients, animation, transition)이 포함된다.

    CSS4는 없다. CSS3에서 확장될 뿐이다.

    Email에서의 CSS

    이메일에서 external css는 동작하지 않는다. 이메일 전송 프로토콜인 SMTP server에서 이를 허락하지 않기 때문이다.

    <head> 태그에 <style> 태그를 삽입해도 되지만, 구식 이메일 클라이언트에서 이를 지원하지 않는 경우도 있다.

    결론은 inline 방식으로 스타일링하는게 가장 안전하다.

    Promise.all vs Promise.allSettled

    • Promise.all

      • 프라미스가 하나라도 거절되면 전체를 거절
      • 프라미스 결과가 모두 필요할 때같이 ‘모 아니면 도’ 일 때 유용
    • Promise.allSettled

      • 각 프라미스의 상태와 값 또는 에러를 받을 수 있다.
      Copy
      [
        { status: 'fulfilled', value: ...응답... },
        { status: 'fulfilled', value: ...응답... },
        { status: 'rejected', reason: ...에러 객체... }
      ]

    <table>에 padding 주기

    table과 관련있는 몇몇 요소들 - thead, tr 등 - 에는 padding이 적용 안된다.. table 자체 또는 th, td에 먹어야 한다.

    아니면 border-collapse 속성을 사용하여 표(table)의 테두리와 셀(td)의 테두리 사이 간격을 조정하는 방법도 있는데…

    01

    이건 내가 원하는 게 아닌 것 같다. ‘테두리’ 사이 간격을 조정하고 싶은 건 아니니까 😖

    Ref

    next.js image loader

    next/image를 사용해서 이미지를 로드한 후 next export하면, next.js의 기본 loader 설정을 따르게 된다. 그러나 이 기본 loader 설정은 next export를 통해 생성되는 정적 HTML 파일에서 사용할 수 없는 Image Optimization API를 사용하기 때문에, 정상적으로 로드되지 않을 수 있다.

    이 문제를 해결하려면, next.config.js에 loader 설정을 바꾸거나 이미지에 unoptimized 설정을 해줘야 한다.

    그러나 이때 Missing loader Prop on next/image가 발생하는 경우도 있는데, next/image를 정상적으로 로드하려면 컴포넌트에 loader prop을 제공해줘야 한다?! (또는 next.config.js에 명시한다.)

    loader의 역할은, 배포 도메인에서도 이미지의 정확한 path를 찾게 해주는 것인 듯 하다.

    Copy
    const myLoader = ({ src, width, quality }) => {
      return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
    };
    
    const MyImage = (props) => {
      return (
        <Image
          loader={myLoader}
          src="/me.png"
          alt="Picture of the author"
          width={500}
          height={500}
        />
      );
    };

    프로젝트에서는 akamai loader를 사용하여 다음과 같이 작성했다.

    Copy
    // next.config.js
    module.exports = {
      images: {
        loader: "akamai",
        path: env.URL,
      },
      // ...
    };

    왜 이따구로 불편하게 해놨는지 모르겠다… 이미지 최적화를 위해서라지만 프로덕션 배포 시에도 좀 알아서 처리 좀 해주지. 공식 문서에 설명도 똥같이 해놓고, 짱나게.

    Ref


    이것저것

    • 정규표현식을 작성할 때 [ㄱ-힇]으로 작성하면 엔진에 따라 한국어 전 범위를 포함할 수도 있고 포함하지 않을 수도 있다.

      • 따라서 한국어 전 범위를 포함하려고 할 때 [\u3131-\uD7A3]와 같이 유니코드로 표현하는게 안전하다.
    • peerDependency가 명시된 패키지는 peerDependency가 외부 의존성으로 그대로 남은 채로 빌드된다. 즉 import/require문이 남은 상태로 빌드된다.

    • 객체 구조분해할당과 property shorthand를 조합하여 자바스크립트 런타임의 pick을 흉내낼 수 있다 (객체에서 몇몇 프로퍼티만 빼오는 것)

      Copy
      const object = { a: 5, b: 6, c: 7 };
      const picked = (({ a, c }) => ({ a, c }))(object);
      
      console.log(picked); // { a: 5, c: 7 }

    기타공유

    scriptkit

    자바스크립트로 스크립트를 작성해서 일상적인 문제들을 해결할 수 있게 해주는 도구로, 알프레드의 자바스크립트 버전이다.

    작성법, 실행법 그리고 스크립트 import가 쉽다는 것이 장점이다.

    다음과 같은 기능들을 수행할 수 있다고 한다.

    • 해커 뉴스를 브라우징하기 위한 스크립트 작성
    • Script Kit로 크롬 개발자 도구 즉시 실행하기
    • Apple Events를 사용하여 Script Kit에서 크롬 제어하기
    • 드래그 앤 드롭으로 이미지 조작하기
    • 개발 프로젝트 목록화하고 실행하기
    • 모든 텍스트에 Title Case 적용하기
    • 크롬 탭들을 마크다운 파일에 저장하고 메모하기
    • 웹사이트 추출 스케줄링하기
    • 여러 탭에 걸친 투두리스트 앱 만들기

    Ref https://www.scriptkit.com/

    TypeScript 5.0

    메이저 버전 업데이트라니.. 😮 싱기하다. 별 내용은 없다고 한다.

    • Decorators 지원

    • const 접근자를 사용한 Type Parameters

      Copy
      type HasNames = { names: readonly string[] };
      function getNamesExactly<const T extends HasNames>(arg: T): T["names"] {
      //                       ^^^^^
          return arg.names;
      }
      
      // Inferred type: readonly ["Alice", "Bob", "Eve"]
      // Note: Didn't need to write 'as const' here
      const names = getNamesExactly({ names: ["Alice", "Bob", "Eve"] });
    • extends에 여러 설정 파일 지원

    • 모든 enum은 Union enum

    • --moduleResolution: bundler 지원

    • Resolution 커스텀 플래그

    • --verbatimModuleSyntax

      Copy
      // Erased away entirely.
      import type { A } from "a";
      
      // Rewritten to 'import { b } from "bcd";'
      import { b, type c, type d } from "bcd";
      
      // Rewritten to 'import {} from "xyz";'
      import { type xyz } from "xyz";
    • export type * 지원

    • JSDoc에 @satisfies 지원

    • JSDoc에 @overload 지원

    • --build 명령어에 Emit-Specific 플래그 지원

    • Exhaustive switch/case 구문에 대한 scaffold 제공

    • 속도, 메모리, 패키지 사이즈 최적화

    등등의 기능이 추가되었다고 한다.

    타입스크립트 공식 릴리즈 문서는 참 가독성이 떨어진다. 말이 너무 많아. 🗣️

    Ref https://devblogs.microsoft.com/typescript/announcing-typescript-5-0-beta/

    typewind

    tailwind에 타입 시스템의 적용이라니… 😮

    그건 그렇고 문서 보다가 발견한 typewind의 modifier. 신박한 방식인 것 같다. 체이닝이라니

    Copy
    import { tw } from "typewind";
    
    export default function Button() {
      return (
        <button
          className={tw.bg_blue_500
            .hover(tw.bg_blue_600)
            .text_white.rounded.py_3.px_4.md(tw.py_4.px_5)
            .dark(tw.bg_sky_900.hover(tw.bg_sky_800))}
        >
          Click Me
        </button>
      );
    }

    Ref https://typewind.vercel.app/


    마무리

    친한 언니의 집들이를 다녀왔다. 온갖 트렌디한 매장들이 들어선 주상복합 신축 아파트에 방도 세련되게 잘 꾸며놔서 너무너무 부러운 집이었다. 나도 열심히 일해서 좋은 곳에서 멋지게 살아야겠다는 다짐을 다시 해본다 😎


    Relative Posts:

    2월 첫주차 기록

    February 4, 2023

    1월 3주차 기록

    January 20, 2023

    zigsong

    지그의 개발 블로그

    RotateLinkImg-iconRotateLinkImg-iconRotateLinkImg-icon