August 6, 2022 • ☕️☕️ 9 min read
합주는 즐거워
Create React App Configuration Override 의 약자로, 말 그대로 CRA에서 config를 덮어쓸 때 사용한다. 비슷한 툴로는 react-app-rewired가 있다.
최근에는 사용률 측면에서 craco가 react-app-rewired를 따라잡고 있는데, 그 이유는 CRA 2.0 버전부터 “lightly” 하게만 관리한다고 선언했기 때문이 아닌가 싶다.
craco를 만든 이유를 읽어보면 관련 내용이 나온다. webpack이 너무 어렵기 때문에 만들었다고 한다… 😂 react-app-rewired를 쓰고 있었는데, 더 이상의 패키지 업데이트를 중단하겠다고 해서 탄생한 게 CRACO다!
react-app-rewired
는 CRA 2.0버전부터는 “lightly”하게 지원한다.react-app-rewired
README를 보면 다음과 같이 적혀있다. “As of Create React App 2.0 this repo is “lightly” maintained mostly by the community at this point.” 패키지를 lightly하게 관리한다는 것은, 문맥상 오픈소스를 관리하는 메인테이너가 직접 코드를 수정하지 않고 커뮤니티의 풀 리퀘스트가 있을 때 approve & merge 해주는 정도라고 생각할 수 있다. 질문과 별개로 저는 craco, react-app-rewired 등 고민했었는데 결국
craco, react-app-rewired와 비슷한 도구로, patch-package라는 것도 있다. patch-package는 직접 node_modules
을 수정하고 동료 개발자들이 install할 때 변경사항을 동일하게 반영시켜준다. craco, react-app-rewired 같은 config-override 패키지에 비해 다음과 같은 장점이 있다.
Next.js
에서 HTML을 변경하기 위해서는 Custom Document를 이용해야 한다.
Next.js
10.2 버전부터는 web font 최적화를 내장시켜 FCP 및 LCP를 개선했다.
AbortController는 비동기 요청을 중단할 수 있는 인터페이스를 제공한다.
AbortController.signal
: 새로운 AbortController 객체 인터페이스를 생성한다.AbortController.abort()
: 비동기 요청이 완료되기 전에 취소한다.abort
이벤트에 대해 리스터를 등록할 수 있다.SSG는 빠른 퍼포먼스가 필요할 때, 정적인 컨텐츠를 렌더링할 때 적합한 방식이라 할 수 있고, SSR은 항상 최신 상태를 유지해야하는 동적인 컨텐츠를 렌더링할 때 적합하다고 할 수 있다.
SSG는 응답 속도가 매우 빠르다는 이점이 있다. 그렇다면 컨텐츠의 최신화 빈도가 크지는 않지만 완전히 정적인 데이터라고 볼 수는 없는 데이터를 다룰 때, SSG를 사용할 수는 없을까?
Next.js SSG는 컨텐츠를 얼마 주기로 다시 빌드하는지를 체크하는 기능이 있다. 특히 데이터의 변경이 자주 일어나지 않는 곳은, cdn까지 붙이면 전달속도를 훨씬 향상시킬 수 있다.
getStaticProps
에 revalidate
prop을 넣으면 되는데, revalidate
값에 해당하는 초단위 시간이 지나면 Next.js는 우선 캐시된 상태의 현재 페이지를 보여주면서 백그라운드에서는 재빌드를 진행하고, 이것이 성공하면 업데이트된 페이지를 보여준다.void 0
은 void(0) => undefined
값을 반환한다.
undefined 값을 직접 사용하지 않고 void 0을 사용하는 이유는 무엇일까?
자바스크립트의 초창기 시절 undefined는 writable한 전역 변수였다. (즉, undefined에 값을 할당할 수 있었다) 이때 값이 할당된 undefined로 인한 버그를 막기 위해 void 0 이라는 코드를 사용하게된 것이다. (최신 브라우저에서는 undefined에 값을 할당할 수 없다.)
타입스크립트의 튜플은 참 신기해요 🐳
tuple은 자바스크립트에는 없는, 타입스크립트만의 문법이다. 배열 타입을 보다 특수한 형태로 사용할 때 tuple을 사용한다.
튜플에서는 명시적으로 지정된 형식에 따라 아이템 순서를 설정한다.
let myInfo: [string, number] = ["지그", 26];
myInfo = [26, "지그"]; // 🚨 Error
튜플에서는 순서와 길이가 보장된다.
myInfo[0]; // "지그"
myInfo[1]; // 26
myInfo[2]; // 🚨 Error
인덱스 타입도 불변이며, 컴파일러가 그 정확한 값을 기억하고 있다.
즉 아래 코드는,
const days = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] as const;
아래와 같은 형태로도 작성할 수 있다.
{
0: 'sun',
1: 'mon',
2: 'tue',
3: 'wed',
4: 'thu',
5: 'fri',
6: 'sat',
readonly length: 7,
}
일반적인 배열과 튜플은 타입이 추론되는 방식이 서로 다른다.
const daysArray = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"];
type daysArrayTytpe = typeof daysArray; // string[]
const daysTuple = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"] as const;
type daysTupleType = typeof daysTuple; // readonly ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]
튜플은 불변 구조이기 때문에 readonly
키워드를 명시적으로 수식한다. 튜플은 적은 양의 연결된 데이터, 또는 고정된 데이터 타입을 위한 패턴으로 사용할 수 있다.
Ref https://yamoo9.gitbook.io/typescript/types/tuple https://blog.cometkim.kr/posts/typescript-tuples/
패키지를 링크로 만들 때 - npm link
워크스페이스로 링크를 자동화할 때 - npm workspace
워크스페이스로 의존성을 하나로 관리할 수 있다.
각 npm 프로젝트의 의존성과 스크립트를 한 곳에서 관리할 수 있게끔 해준다.
🤔 서로다른 npm 프로젝트에서, 같은 의존성의 다른 버전을 사용한다면?
require(workspace-a)
npm start -w workspace-a
Ref https://jeonghwan-kim.github.io/2022/07/31/npm-workspace https://d2.naver.com/helloworld/0923884
// plugins/eslint/index.js
module.exports.rules = {
// ...
"no-window-open": {
create: (context) => {
return {
MemberExpression(node) {
const { object, property } = node;
console.log(object.name);
if (object.name === "window" && property.name === "open") {
context.report({
node,
message:
"window.open() 대신 Link utils의 openWindow()를 사용해주세요.",
});
}
},
};
},
},
};
여기서 MemberExpression 클래스는, 필드 또는 속성에 대한 액세스를 나타낸다.
<th>
의 기본 font-weight
은 700이다.role=“separator”
지정 시, aria-orientation
의 기본값은 horizontal이다. (divider에 적용할 수 있다.)color.replace(/,\s+/g, ',').match(/^rgba?\((\d+),+(\d+),+(\d+),?([.\d]+)?\)$/i)
--cache
옵션을 추가하면 변경된 파일에 대해서만 린트 실행해준다 (Ref)!default
- 자바스크립트의 default parameter
처럼 scss
에서 기본값을 넣어주는 플래그React.isValidElement(object)
- 객체가 React 엘리먼트인지 확인한다. true
또는 false
를 반환한다.URL.toString()
메서드 (Ref)new RegExp()
로 쓰면 호출될 때마다 새로 컴파일되는 반면에 //
로 쓰면 딱 한번 컴파일 되서 성능이 더 좋다. (Ref)이 친구는 정말 fancy해질 것만 같다… Meta Open Source라고 한다. 메타 오픈소스가 뭐지? 더 엄청난 오픈소스인가? 하고 생각했는데, 페이스북의 그 메타였다 😅
다음과 같은 기능들이 추가되었다고 한다.
npm downloads에서도 Docusaurus 2.0을 쓴다고 한다!
Ref https://docusaurus.io/blog/2022/08/01/announcing-docusaurus-2.0
C++, Rust가 아닌 시스템 하드웨어에서 읽을 수 있는 저수준 프로그래밍 언어인 Zig로 작성되어있어 더 빠르게 동작할 수 있는 것으로 보입니다.
우와! Zig가 여기서 쓰였다니, 반갑당
아무튼 간에, Node나 Deno보다 훨씬 빠르다고 한다!
Ref https://techblog.gccompany.co.kr/한bun-써보는-거-어때-fa3cb32ac76f
Typescript type으로 만든 zero runtime Typescript type checker로, Typescript의 type이 튜링 완전하다는 사실 (최소한 2.2버전은 튜링 완전)에서 출발한 프로젝트다. (코드를 실행하지 않고 그저 코드를 문자열로 전달하면 즉시 에러를 확인할 수 있다)
완전히 흥미 위주인 프로젝트지만, 튜링 완전하다는 것의 의미와 그 구현법들을 통해 더 다양한 타입스크립트의 활용을 기대해볼 수 있다.
Hype라고 하니 뉴진스의 Hype boy만 떠오르는 나는… 개노답이다 😩
Ref https://github.com/ronami/HypeScript
결국 체념하고 블로그를 하나하나 옮기고 있다~ 160개가 넘는 글을 다 옮긴다니… 아마 광복절이 지나서야 새 블로그를 출간할 수 있지 않을까 싶다. ㅎㅎ
요즘은 회사에서 지원해주는 밴드에서 드럼을 치고 있다. 진짜 너무너무너무너무 재밌다… 이세상에 드럼만큼 재밌는 게 또 있을까. 함께 하는 구성원 분들과도 합이 잘 맞고 넘 즐거워서 평생해도 될 것 같다.
사원증 사진 촬영을 했다. 맘에 들게 잘나왔당. 입사동기 분들도 처음으로 만나고, 오전 내내 농땡이 부리다가(?) 회사로 복귀했다. 빨리 사진 들어간 사원증 받아보고 싶다!