October 1, 2022 • ☕️☕️ 11 min read
호주 가보자고
development
: 프로토타이핑 및 개발 용도. npm run serve
명령어로 실행할 때의 모드production
: 상용화 및 배포 용도. npm run build
명령어로 실행할 때의 모드test
: 테스트 용도. npm run test:unit
명령어로 실행할 때의 모드인증과 인가는 엄연히 서로 다른 프로세스이므로 각 용어에 따른 개념을 각각 이해하는 것이 중요하다.
Oauth 2.1 의 인증/인가 흐름은 다음과 같다.
Ref https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-05#section-1.2
클로저를 사용할 때 stale closure 문제를 주의해야 한다.
다음 코드를 살펴보자. WatchCount
컴포넌트의 useEffect
hook에서는 매 2초마다 count
값을 콘솔에 로깅한다. 그리고 button
을 통해 count
의 값을 증가시킬 수 있다.
function WatchCount() {
const [count, setCount] = useState(0);
useEffect(function () {
setInterval(function log() {
console.log(`Count is: ${count}`);
}, 2000);
}, []);
return (
<div>
{count}
<button onClick={() => setCount(count + 1)}>Increase</button>
</div>
);
}
실행해보면, button
으로 count
의 값을 여러 번 증가시켜도, useEffect
hook 내부에서 출력되는 count
의 값을 계속 0이다.
컴포넌트가 마운트된 후, useEffect
는 setInterval
함수를 호출하고, setInterval
은 console.log()
를 2초마다 출력하기로 스케쥴링했는데, 이때 클로저가 된 console.log()
함수가 count
변수의 초기값 0을 계속 물고 있기 때문이다. 즉 console.log9)
가 stale closure가 된 것이다.
해결 방안은 useEffect
에게 console.log()
가 count
의 값에 의존하고 있음을 알려주는 것이다.
function WatchCount() {
const [count, setCount] = useState(0);
useEffect(
function () {
const id = setInterval(function log() {
console.log(`Count is: ${count}`);
}, 2000);
return function () {
clearInterval(id);
};
},
[count]
);
// ...
}
useEffect
의 dependency에 count
를 넣어, count
가 변할 때마다 클로저를 업데이트하게끔 한다.
Ref https://dmitripavlutin.com/react-hooks-stale-closures/#3-stale-closures-of-hooks
env-cmd
를 사용할 때 공통으로 사용하는 환경변수를 두고 특정 상황마다 분기를 주고 싶다면 아래와 같이 사용하면 된다.
// .env-cmdrc
{
"dev": {
"ENV1": "Thanks",
"ENV2": "For All"
},
"dev02": {
"ENV1": "The Fish"
}
}
// package.json
"scripts": {
"build:dev02": "env-cmd -e dev,dev02 react-scripts build",
}
이렇게 사용하게 되면 dev에 있는 환경변수를 사용하면서 dev와 dev02에 모두 존재하는 환경변수의 경우 dev02의 값으로 사용한다.(dev의 값을 덮어씌운다.)
이 때 주의할 점은 dev, dev02
처럼 띄어쓰면 안 되고 dev,dev02
처럼 붙여서 사용해야 한다.
“prepare”에 스크립트를 추가하면 npm ci
만 실행해도 install
후에 자동으로 실행된다. npm ci
의 실행 순서가 다음과 같기 때문이다.
Ref
as
타입스크립트에서 as
는 그냥 타입 단언(type assertion)용으로만 쓰는 줄 알았다..!
그런데 as
를 활용해서 key remapping도 할 수 있다고 한다.
type MappedTypeWithNewProperties<Type> = {
[Properties in keyof Type as NewKeyType]: Type[Properties];
};
template literal type 등의 기능을 활용해서, 새로운 프로퍼티 이름을 정의할 수도 있다.
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<
string & Property
>}`]: () => Type[Property];
};
interface Person {
name: string;
age: number;
location: string;
}
type LazyPerson = Getters<Person>;
// type LazyPerson = {
// getName: () => string;
// getAge: () => number;
// getLocation: () => string;
// }
이밖에 또 여러 가지로 활용할 수 있는 길들이 있으니 참고하자~!
Ref https://www.typescriptlang.org/docs/handbook/2/mapped-types.html#key-remapping-via-as
웹사이트의 방문자를 분석하는 웹로그 분석에 많이 사용하는 분석 기법으로, 웹페이지에서 발생하는 마우스 클릭을 열분포 형태의 이미지로 변환하여 보여준다.
근데 hitmap인지 heatmap인지 모르겠다… 🙄 사용자가 특정 요소를 선택했다면(클릭했다면) hit가 맞는 것 같기도, 어떤 곳을 ‘많이’ 클릭했는지를 알고 싶다면 ‘열’을 뜻하는 ‘heat’가 맞는 것 같기도 하다. 둘 다 사용하고 있는 것 같다.
Ref
AxiosPromise
라는 타입이 정의되어 있다.
export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {}
LDAP은 네트워크상에서 조직이나 개인, 파일, 디바이스등을 찾아볼 수 있도록 하는 소프트웨어 프로토콜이다.
예전부터 이름을 통해 쉽게 찾아낼 수 있는 시스템을 구축하는데 많은 고민과 시간을 쏟았다. (e.g. DNS) 이러한 것들을 전자 디렉토리 서비스라고 부른다.
그러한 표준 (X.500)을 만들고, 이 표준을 기반으로 클라이언트가 디렉토리 시스템과 상호작용하는 방식인 DAP(Directory Access Protocol)가 탄생했다.
DAP는 OSI Model을 기반으로 만들었기 때문에, 흔히 쓰이던 TCP/IP Model에서도 동작할 수 있도록 만들어야 했다. 그래서 나온게 LDAP(Lightweight Directory Access Protocol)다.
DAP는 OSI의 모든 계층을 사용하기 때문에 무겁고 네트워크 트래픽을 많이 소요했다. 그래서 계층이 적은 TCP/IP Model을 사용하면서 이러한 부분을 함께 개선하고자 했고, TCP/UDP로 해결할 수 있도록 경량화 시켰다. 이것이 LDAP에 ‘Lightweight’가 붙는 이유이며, 지금도 많이 쓰이는 표준이다.
LDAP는 이름 기반으로 찾아내는 특성상 RDN(Relative Distinguished Name) 값을 각 Entity 별로 갖고 있으며, 이어붙여 트리상에서 Entity를 쉽게 검색할 수 있다는 점이 특징이다.
Ref https://vallista.kr/LDAP-(Lightweight-Directory-Access-Protocol)/
타입스크립트 4.9 베타 버전이 올라왔다.
satisfies
연산자
표현식이 어떤 타입에 매칭됨을 보장하면서도, 가장 구체적인 타입을 작성하고자 할 때 사용한다. 표현식의 타입을 바꾸지 않으면서, 표현식의 타입이 어떤 타입과 매칭되는지 검증해주는 것이다.
type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number];
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255]
// ~~~~ The typo is now caught!
} satisfies Record<Colors, string | RGB>;
// Both of these methods are still accessible!
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();
palette
의 타입을 Record<Colors, string | RGB>
로 제한하는 대신, satisfies
연산자를 사용함으로써 bleu
의 typo도 찾아낼 수 있음은 물론, palette
의 모든 프로퍼티가 string | number[]
타입임을 검증하여 red
와 green
에서 프로토타입 메서드 (at()
, toUpperCase()
)를 사용할 수 있게 되었다.
in
연산자로 list되지 않은 프로퍼티 좁히기
런타임에 특정 프로퍼티가 존재하는지 여부를 알기 위해 타입스크립트는 (자바스크립트 문법인) in
연산자를 사용한다. 하지만 주어진 프로퍼티에 타이핑이 되어있지 않다면 도움이 되지 않는다.
interface Context {
packageJSON: unknown;
}
function tryGetPackageName(context: Context) {
const packageJSON = context.packageJSON;
// Check to see if we have an object.
if (packageJSON && typeof packageJSON === "object") {
// Check to see if it has a string name property.
if ("name" in packageJSON && typeof packageJSON.name === "string") {
// ~~~~
// error! Property 'name' does not exist on type 'object.
return packageJSON.name;
// ~~~~
// error! Property 'name' does not exist on type 'object.
}
}
return undefined;
}
packageJSON
의 타입이 unknown
에서 object
로 좁혀졌지만, in
연산자는 타입을 엄격하게 확인하기 때문에 packageJSON
에 name
프로퍼티가 있다는 것을 보장할 수 없다.
타입스크립트 4.9에서부터 in
연산자는 프로퍼티를 전혀 기재하지 않아도 타입을 추론하는 방식으로 변경되었다. 이제 packageJSON
은 object & Record<"name", unknown>
타입이 되어, packageJSON.name
을 직접적으로, 그리고 독립적으로 사용할 수 있게 된다.
NaN
의 동일성 체크
자바스크립트에서 NaN
은 특수한 숫자형 값으로, NaN
과 NaN
은 서로 동일하지 않다. 타입스크립트 신규 버전에서는 NaN
과 직접적으로 비교 연산을 수행하는 것을 금지한다. (대신 Number.isNaN
의 사용을 권장한다.)
function validate(someValue: number) {
return someValue !== NaN;
// ~~~~~~~~~~~~~~~~~
// error: This condition will always return 'true'.
// Did you mean '!Number.isNaN(someValue)'?
}
File System Events에 기반한 File-Watching 이전 버전에서 타입스크립트는 개별 파일을 watching하는 데 polling 방식을 사용했다. polling은 정해진 시간마다 업데이트를 확인하는 것으로, CPU가 계속해서 방해받게 된다. 타입스크립트 4.9에서는 특정 파일의 업데이트 시 콜백을 실행하는 파일 시스템 이벤트를 활용한다.
기타 오류 수정 및 Breaking Changes
Promise.resolve
의 더 나은 타이핑exports
가 typesVersions
보다 우선시됨substitute
를 SubstitutionTypes
의 constraint
로 대체Ref https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-beta/
Ref https://events.geekle.us/react3/
펫의 종류가 더 다채로워진 것 같다! 클립이 있다니 ㅋㅋㅋ
Ref https://github.com/tonybaloney/vscode-pets
여러 가지 비밀(?)스러운 소식들이 있었고… 인생 첫 사회인으로써 청첩장을 받아봤다! 좀 늦은 것 같기도..? 내가 다 기대되고 설렌당. 결혼식을 아직 많이 안 가봐서 그런지, 결혼식 넘 재밌당. 주변에 결혼하시는 분들이 점점 많아지는 것 같다.
내년 호주 같이 갈 회사 친구들(ㅋㅋ)을 만났다. 새로 알게 된 언니는 정말 텐션이 장난 아니다. 무사히 갔다올 수 있겠지?
이제 개천절까지 연휴다! 너무너무 좋당. 주4.5일제를 하고 있긴 하지만, 주4일제 소취… (국가적으로)