April 1, 2023 • ☕️☕️ 10 min read
고오-급 스테이크🥩와 동물 친구들🦘🐨
vite는 import.meta.env
를 통해 환경변수에 접근하도록 하고 있다 (공식문서)
다만 외부 라이브러리가 process.env
를 사용한다면 process is not defined 에러
를 마주할 수 있는데, vite.config
에 defined['process.env'] : {}
로 빈 env를 정해서 넘어갈 수 있다.
다만 실제로 process.env
가 비어있기 때문에 빈값에 대한 오류가 발생할 수 있으니 적절한 값을 채워넣음으로써 해결해야할 수도 있다.
export default defineConfig({
// ...
define: {
"process.env": {},
},
});
exports
storybook은 기본적으로 webpack 4를 사용하기 때문에, package.json의 exports field를 지원하지 않는다.
package.json의 exports field는 패키지가 node_modules lookup이나 이름으로 import되었을 때의 엔트리 포인트를 지정해준다. 패키지 모듈을 여러 환경에서 사용하게 해주면서도, 내부 파일에 대한 접근을 제한할 수 있는 방법을 제공한다.
{ "exports": { ".": "./main.js", "./sub/path": "./secondary.js", "./prefix/": "./directory/", "./prefix/deep/": "./other-directory/", "./other-prefix/*": "./yet-another/*/*.js" } }
👆 webpack4까지는 위 기능이 지원되지 않았던 것 같다.. 😕
따라서 storybook으로 빌드하는 외부 의존성 모듈이 exports field를 사용한다면 storybook이 webpack5를 사용하도록 추가 구성을 해줘야한다.
cf) storybook 6.2버전부터 webpack 5를 지원한다
Ref https://nodejs.org/api/packages.html#exports
emotion 등의 라이브러리의 같은 버전을 사용하더라도, react를 17을 쓰냐 18을 쓰냐에 따라서 내부적으로 다른 버전의 resolution을 사용한다. 이 경우 emotion은 버전이 같더라도 아예 다른 모듈로 취급돼서 문제가 발생한다.
예를, 들어 프로젝트 환경은 emotion 11.10.0, react 17.0.0인데, 가져오는 라이브러리 A가 emotion 11.10.0, react 18.0.0이라고 가정하면 라이브러리에서 사용하는 emotion과 프로젝트에서 사용하는 emotion은 다르다.
pnpm같은 non-flat 패키지 매니저의 경우 이 두가지 모듈을 모두 가지고 있다. 이때, 아래와 같은 경우 타입에러가 발생할 수 있다.
// library-A. react 18.0.0 emotion 11.10.0
import styled from "@emotion/styled";
const A_Component = styled.div``;
// project. react 17.0.0 emotion 11.10.0
import { A_Component } from "@library-A";
import styled from "@emotion/styled";
const Component = styled(A_Component)``; // 🚨 Type Error
같은 emotion 버전의 styled
키워드로 선언했더라도, react 버전이 다르기 때문에 내부에서 사용하는 resolution이 다르기 때문에 styled
의 타입이 아예 다르다. 그렇기에 상속이 불가능하다는 타입 에러가 발생한다.
👉 해결방법: react 버전을 맞춘다.
axios에서는 adapter
를 이용해 HTTP 요청을 처리한다. adapter
는 브라우저와 node 환경에서 서로 다른 구현을 가진다.
브라우저
Node.js
http
모듈을 사용한 adapter로 HTTP 요청 처리axios adapter가 하는 일 요약
axios
가 사용할 수 있는 형태로 반환한다.adapter를 커스터마이징해서 사용할 수도 있다.
const customAdapter = (config) => {
const defaultAdapter = axios.defaults.adapter;
return defaultAdapter(config);
};
const axiosInstance = axios.create({
adapter: customAdapter,
});
🔫 트러블슈팅 기록
[TypeError: adapter is not a function]
axios를 사용할 때 이 에러가 발생한다면 axios adapter를 만들지 못 했을 수 있다.
window
global
이 undefined일 경우 이런 에러가 발생할 수 있다. (ex. Next.js middleware 내부)
Next.js middleware는 서버 사이드에서 실행된다. window
객체는 웹 브라우저의 전역 객체로 브라우저 환경에서만 존재하기 때문에 서버 사이드에서 실행 되는 middleware는 브라우저 환경이 없기 때문에 window
객체에 접근할 수 없다.
🤔 Next.js middleware가 서버 사이드에서 실행되면 SSG만 사용할 때는 서버가 없으니 사용을 못 하나? 👉 가능하다. Edge Functions을 통해 Middleware를 엣지 레이어에서 실행할 수 있다. (Vercel은 자동으로 해주고, AWS CF를 사용중이라면 Lambda@Edge를 사용하면 된다.)
moduleResolution: "bundler"
TypeScript 5에서는 moduleResolution
의 옵션으로 bundler
가 추가되었다.
TypeScript는 자바스크립트의 동작을 모델링한다. 마찬가지로 자바스크립트의 module resolution 동작도 모델링한다.
4.7에서는 node16
, nodenext
들이 등장했지만, 제약이 있었다. ESModule방식으로 module을 resolution할 때 항상 파일의 확장자를 붙여줘야 한다는 것이었다. 많은 모던 번들러들이 ECMAScript 모듈과 CommonJS lookup rules을 합쳐서 사용하는 데에 비하면 너무 불편한 방식이다.
그래서 이런 모듈 번들러들의 동작을 모델링해서 bundler
라는 옵션을 추가했다. (원래 이름은 hybrid였는데 최종적으로는 bundler가 되었다.)
vite, esbuild, swc, webpack, parcel 등을 사용할 때는 bundler
라는 옵션을 사용해볼 수도 있을 것 같다!
다음은 moduleResolution 옵션들을 비교한 표.
공통점
차이점
사용 사례
최근에 꽤 주목할 만한 제로데이가 열린 듯 하다 👉 http://m.boannews.com/html/detail.html?idx=115658
테이블에 대한 검색의 속도를 높여주는 자료 구조로, 메모리 영역의 일종의 목차를 생성하는 개념이다. 목차를 이용하여 검색 범위를 줄여 속도를 높일 수 있습니다.
nest.js에서는
@Index
데코레이터로 DB indexing을 해줄 수 있다! 😲
Ref
어느 페이지에서 에러가 발생하여 ErrorBoundary의 fallback으로 떨어지고 페이지를 이동했는데도(라우터 변경) 여전히 fallback 페이지를 렌더링하고 있는 이유는…
ErrorBoundary에서 render
가 어떻게 생겼는지부터 보자.
render() {
if (this.state.hasError) {
return <h1>An error has occurred.</h1>
}
return this.props.children;
}
ErrorBoundary의 state가 정해지면, state가 바뀔 때까지 에러 메시지만 보여줄 것이다. 그러면 히스토리가 바뀌어도 자식 컴포넌트들은 렌더링되지 않는다.
따라서 히스토리가 변경되면 에러 state를 초기화시켜주는 방법을 써야 하는데, history
객체에 이벤트리스너를 붙여주는 방법이 있지만 react-router v6부터는 사용이 쉽지 않다. 😕
이때 ErrorBoundary
에 key
를 넣어주면, 각 페이지마다 서로 다른 컴포넌트로 인식해 에러 상태를 새로 리셋해줄 수 있다.
<ErrorBoundary onReset={reset} fallback={fallback} key={pathname}>
{children}
</ErrorBoundary>
웹사이트에 사용되는 태그를 관리하는 툴로, GTM을 통해 추가한 태그를 통해 웹사이트 사용자의 행동을 분석 및 판단할 수 있다. 컨테이너라는 통로를 통해 웹사이트와 GTM이 연결되고, GTM에서 설정한 태그를 통해 웹사이트 행동 관련 데이터를 수집한다.
초기 세팅 이후에는 개발자의 도움 없이 간단하게 태그를 추가, 삭제할 수 있다.
→ 사이트 및 사용자 분석을 위해 데이터 수집이 필요할 때, 개발자가 아니더라도 손쉽게 스크립트 태그를 생성하고 관리할 수 있게 해주는 툴
Next.js는 blocking data 요청이 없다면 자동으로 페이지가 정적인지(prerender될 수 있는지)를 결정한다. 페이지에 getServerSideProps
와 getInitialProps
가 없다면 정적 페이지라고 판단한다.
이 기능을 통해 Next.js는 서버 렌더링 페이지(SSR)와 정적 생성 페이지(SSG)를 모두 포함하는 하이브리드 앱을 만들 수 있다.
Response
인터페이스의 json()
메서드는 Response
스트림을 받은 후 읽어서 완료한다. body text를 JSON으로 파싱한 결과물을 resolve하는 promise를 리턴한다.
메서드 이름은 json()
이지만, 반환값은 JSON이 아니라 JSON을 input으로 받아서 새로운 자바스크립트 객체로 파싱한 결과물이다.
axios 말고 오랜만에 fetch 쓰면서 .json()
을 사용하다 보니까 괜히 낯설어서… 🫠
Ref https://developer.mozilla.org/en-US/docs/Web/API/Response/json
H
를 통해 호스트 네임을 줄 수 있다.
npx next dev -H 192.168.1.2
min-height
만 적용되어있으면 자식 속성의 height: 100%
CSS 가 먹지 않는다. 부모에 height: 1px
이라도 주면 정상적으로 동작한다.<dialog>
tag는 생각보다 많은 기능들을 지원하고 있다. (dialog 요소가 가진 슈퍼 파워 알아보기)그냥 구글링과의 차이점이라면, 문맥을 파악하여 원하는 답을 내준다는 것. 그리고 답의 출처를 알려줘서 추가 학습이 가능하게끔 해준다는 것! 잘 사용하면 써볼 만도 하겠다.
Ref https://yozm.wishket.com/magazine/detail/1944/
또 좋은 정리 문서가 나왔다! 오히려 우테코하며 더 전전긍긍했던 프론트엔드 디자인 패턴… 지금은 그런 거 하나도 모른다. (🙃) 디자인 패턴 뿐 아니라 렌더링, 퍼포먼스 관련해서도 정리가 되어있다. 틈틈이 읽어나가볼 아이템이 생겼다!
벌써 한글로 번역해주시는 분도 계신다… 역시 머릿수는 적지만 부지런한 K-한국인들.
Ref
1분기가 끝났다. 팀원들 회식하는 기념으로(?!) 나도 호주 와서 첨으로 고오급 스테이크에 와인 잔뜩(2잔..) 내돈내산으로 마시고 취했다… 20만원 나왔지만 행복한 저녁이었다. 🍷🥩
주말엔 코알라, 캥거루도 만났다! 코알라 생츄어리에 진짜 아무데나 널린 코알라와 캥거루들… 이렇게 아무데나 풀어놔도 되나, 가까이 가면 캥거루가 근육질 다리로 차버리는 거 아닌가 걱정했는데 넘 재밌었다. 캥형들은 우락부락 무서버서, 잠만 자는 졸귀탱 코알라 사진으로 🐨