January 28, 2023 • ☕️☕️ 8 min read
7일같은 3일
vitest는 vite를 위한 Unit Test Framework다.
vitest는 기본적으로 watch mode
로 실행되고, CI환경에서는 run mode
로 실행된다.
vitest는 비단 vite 뿐만 아니라 vite를 사용하지 않는 프로젝트에서도 Jest 등의 대안이 되는것을 목표로 개발되고 있다.
병렬 스레드를 사용한 빠른 실행 속도가 장점이다.
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? 참고
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 extension 개발에서 사용자의 데이터와 상태를 지속하는 방법을 제공한다. Indexed DB, localStorage와 비슷하지만 chrome extension에 맞게 디자인되어있다.
Storage API는 다음 네 가지 버킷(스토리지 존)으로 나뉜다.
storage.local
: 데이터는 로컬에 저자되며, extension을 지우면 데이터가 사라진다.storage.sync
: 같은 유저가 로그인된 브라우저라면 브라우저끼리 데이터를 공유한다. 다른 컴퓨터에서 내 크롬아이디로 로그인할 때 북마크가 유지되는 것과 같다.storage.session
: 브라우저 세션 기간 동안 메모리를 유지한다.storage.managed
: readonly 영역으로, 관리자가 세팅할 스키마를 통해 수 있다.Ref https://developer.chrome.com/docs/extensions/reference/storage/
CSS4는 없다. CSS3에서 확장될 뿐이다.
이메일에서 external css는 동작하지 않는다. 이메일 전송 프로토콜인 SMTP server에서 이를 허락하지 않기 때문이다.
<head>
태그에 <style>
태그를 삽입해도 되지만, 구식 이메일 클라이언트에서 이를 지원하지 않는 경우도 있다.
결론은 inline 방식으로 스타일링하는게 가장 안전하다.
Promise.all
Promise.allSettled
[
{ status: 'fulfilled', value: ...응답... },
{ status: 'fulfilled', value: ...응답... },
{ status: 'rejected', reason: ...에러 객체... }
]
<table>
에 padding 주기table과 관련있는 몇몇 요소들 - thead
, tr
등 - 에는 padding이 적용 안된다.. table
자체 또는 th
, td
에 먹어야 한다.
아니면 border-collapse
속성을 사용하여 표(table
)의 테두리와 셀(td
)의 테두리 사이 간격을 조정하는 방법도 있는데…
이건 내가 원하는 게 아닌 것 같다. ‘테두리’ 사이 간격을 조정하고 싶은 건 아니니까 😖
Ref
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를 찾게 해주는 것인 듯 하다.
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를 사용하여 다음과 같이 작성했다.
// next.config.js
module.exports = {
images: {
loader: "akamai",
path: env.URL,
},
// ...
};
왜 이따구로 불편하게 해놨는지 모르겠다… 이미지 최적화를 위해서라지만 프로덕션 배포 시에도 좀 알아서 처리 좀 해주지. 공식 문서에 설명도 똥같이 해놓고, 짱나게.
Ref
정규표현식을 작성할 때 [ㄱ-힇]
으로 작성하면 엔진에 따라 한국어 전 범위를 포함할 수도 있고 포함하지 않을 수도 있다.
[\u3131-\uD7A3]
와 같이 유니코드로 표현하는게 안전하다.peerDependency가 명시된 패키지는 peerDependency가 외부 의존성으로 그대로 남은 채로 빌드된다. 즉 import/require문이 남은 상태로 빌드된다.
객체 구조분해할당과 property shorthand를 조합하여 자바스크립트 런타임의 pick
을 흉내낼 수 있다 (객체에서 몇몇 프로퍼티만 빼오는 것)
const object = { a: 5, b: 6, c: 7 };
const picked = (({ a, c }) => ({ a, c }))(object);
console.log(picked); // { a: 5, c: 7 }
자바스크립트로 스크립트를 작성해서 일상적인 문제들을 해결할 수 있게 해주는 도구로, 알프레드의 자바스크립트 버전이다.
작성법, 실행법 그리고 스크립트 import가 쉽다는 것이 장점이다.
다음과 같은 기능들을 수행할 수 있다고 한다.
Ref https://www.scriptkit.com/
메이저 버전 업데이트라니.. 😮 싱기하다. 별 내용은 없다고 한다.
Decorators 지원
const
접근자를 사용한 Type Parameters
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
// 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/
tailwind에 타입 시스템의 적용이라니… 😮
그건 그렇고 문서 보다가 발견한 typewind의 modifier. 신박한 방식인 것 같다. 체이닝이라니
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/
친한 언니의 집들이를 다녀왔다. 온갖 트렌디한 매장들이 들어선 주상복합 신축 아파트에 방도 세련되게 잘 꾸며놔서 너무너무 부러운 집이었다. 나도 열심히 일해서 좋은 곳에서 멋지게 살아야겠다는 다짐을 다시 해본다 😎