From de191d62f4f0618b4cf632444878b8af79a28012 Mon Sep 17 00:00:00 2001 From: pozafly Date: Sun, 4 Feb 2024 23:50:50 +0900 Subject: [PATCH] =?UTF-8?q?=EB=B0=B0=ED=8F=AC:=202024-02-04?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- css/explore-how-to-apply-modern-css/index.html | 2 +- environment/why-do-you-use-import-meta-in-vite/index.html | 4 ++-- index.html | 2 +- page-data/css/explore-how-to-apply-modern-css/page-data.json | 2 +- .../why-do-you-use-import-meta-in-vite/page-data.json | 2 +- page-data/index/page-data.json | 2 +- page-data/tags/bundler/page-data.json | 2 +- page-data/tags/environment/page-data.json | 2 +- page-data/tags/vite/page-data.json | 2 +- rss.xml | 2 +- tags/bundler/index.html | 2 +- tags/environment/index.html | 2 +- tags/vite/index.html | 2 +- 13 files changed, 14 insertions(+), 14 deletions(-) diff --git a/css/explore-how-to-apply-modern-css/index.html b/css/explore-how-to-apply-modern-css/index.html index 7303638a1..605be7bcb 100644 --- a/css/explore-how-to-apply-modern-css/index.html +++ b/css/explore-how-to-apply-modern-css/index.html @@ -623,7 +623,7 @@

마치며.css-lhozv1{position:relative;box-sizing:border-box;width:100%;max-width:760px;margin-right:auto;margin-left:auto;}
+ );border-radius:3px;}.css-1qcf3bt a{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;}.css-1qcf3bt a:hover{-webkit-text-decoration:none;text-decoration:none;}@media (max-width: 1170px){.css-1qcf3bt{-webkit-flex:1 1 261px;-ms-flex:1 1 261px;flex:1 1 261px;margin-bottom:5vw;}}@media (max-width: 650px){.css-1qcf3bt{display:none;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto;margin:0 25px;padding:0;background:none;}}
Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기

ESLint로 import 구문에 규칙 넣기 cover image
Environment,  ESLint

ESLint로 import 구문에 규칙 넣기

규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.

Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)
Background photo by Voicu Apostol on Unsplash

회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 내부에 묶여있는 eslint, prettier 등의 도구도 latest 버전과 호환이 되지 않았다.

+ );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)
Background photo by Voicu Apostol on Unsplash

회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 패키지 내부에는 eslint, prettier가 vue-cli에 맞게 묶여있었는데 최신 버전의 eslint, prettier 버전을 사용하고 싶어도 호환이 되지 않았다. 그래서 vue-cli 대신 번들러를 바꿔 개발 환경을 최신화하기로 했다.

예전부터 사용해 보고 싶었던 번들러는 Vite다. Vite의 가장 큰 특징은 devServer에서 소스코드와 디펜던시를 두 가지 카테고리로 나누어 빌드하고, ESM 환경인, 브라우저에 빠르게 제공한다는 점이다. devServer가 cold-start 될 때 현재 페이지에서 필요한 정보만 아주 빠르게 실행시킬 수 있다. 이 말은, 코드 베이스 또는 라이브러리(사용하고 있는 node_modules 디펜던시)의 모든 파일을 번들링 하여 제공하는 것이 아니라, 현재 필요한 모듈만 골라내어 빠르게 제공한다는 뜻이다. Vite 가이드에서 가장 먼저 이야기하고 있는 것이 ESM을 통한 devServer start 속도이다.

사전 번들링은, esBuild를 통해 디펜던시를 빌드하고, 변경이 잦은 소스코드는 ESM으로 제공한다. 기존에 Webpack과 같은 번들러는 모든 파일을 빌드 및 번들링 해야만 브라우저에서 구동이 가능했다. Vite는 소스코드를 ESM으로 제공하기 때문에 브라우저에서 동적 import를 통해 원하는 JavaScript 파일만 실행시킬 수 있다. 이 매커니즘에 따라 Webpack의 Node.js에서만 가능했던 기능이 브라우저에서 동작하기 위해 어떻게 Vite가 해결했는지를 알아볼 것이다.


diff --git a/index.html b/index.html index 650269ebf..4453e84d0 100644 --- a/index.html +++ b/index.html @@ -109,7 +109,7 @@ 'M17.5306 13.5882C16.6384 13.8558 15.689 14 14.7044 14C9.5004 14 5.28174 9.97061 5.28174 5.00005C5.28174 3.32422 5.76127 1.75538 6.59643 0.411865C2.77326 1.55853 0 4.96994 0 9.00001C0 13.9706 4.21866 18 9.42265 18C12.8721 18 15.8887 16.2296 17.5306 13.5882Z' );clip-path:path( 'M17.5306 13.5882C16.6384 13.8558 15.689 14 14.7044 14C9.5004 14 5.28174 9.97061 5.28174 5.00005C5.28174 3.32422 5.76127 1.75538 6.59643 0.411865C2.77326 1.55853 0 4.96994 0 9.00001C0 13.9706 4.21866 18 9.42265 18C12.8721 18 15.8887 16.2296 17.5306 13.5882Z' - );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Pozafly's Blog

기록 여정

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.

모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime) cover image
CSS,  Performance

모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)

전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기

ESLint로 import 구문에 규칙 넣기 cover image
Environment,  ESLint

ESLint로 import 구문에 규칙 넣기

규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.

GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys) cover image
DevOps,  GitHub Actions,  Automation

GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys)

restore-keys는 기존 캐시가 쓸모없어졌음에도 불구하고 기존 캐시를 불러오는 기능이다. 그렇다면, 무효화 되지 않은 캐시를 어디에 사용해야 하는 것일까?

Next.js의 API Routes 코드 모듈화에 대해서 cover image
Next.js

Next.js의 API Routes 코드 모듈화에 대해서

API Routes를 사용하면 코드가 매우 지저분해진다. API Routes를 사용하면서 어떻게 하면 코드를 보기 좋은 형태로 남길 수 있을지 고민한 흔적.

글또 8기 회고 cover image
Diary

글또 8기 회고

6개월 간 참여한 글또 활동 회고. 글쓰기에 대해서.

React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법 cover image
React-Query,  React

React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법

React Query의 mutation 실행 이후 클라이언트의 서버 데이터는 변경 되지 않은 상태이다. 화면을 업데이트 하는 여러 가지 방법을 알아보면서, 어떤 상황에서 어떤 방법을 사용해야 하는지 알아보자.

한영타변환기 Alfred Workflow 개발기 cover image
Tool,  Alfred,  Automation

한영타변환기 Alfred Workflow 개발기

dlfjgrp Tjwlseks akfdlek. dlrp sjan Qkrclseks akfdlek. zzzz...

React 렌더링과정으로 알아보는 선언적이라는 의미 cover image
React

React 렌더링과정으로 알아보는 선언적이라는 의미

React는 개발자에게 코드를 선언적으로 작성하도록 한다. 이것을 렌더링 과정과 ErrorBoundary를 통해 알아보자.

React는 Hooks를 배열로 관리하고 있다 cover image
React

React는 Hooks를 배열로 관리하고 있다

왜 Hooks에 이런 제약 조건을 걸었을까? React 내부에서 Hooks를 어떻게 처리하고 있는지, 이렇게 디자인 된 이유는 무엇인지 알아보자.

왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까? cover image
TypeScript

왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까?

TypeScript void 타입을 조금 더 알아보기.

TypeScript의 기본개념과 환경설정 cover image
TypeScript,  Environment

TypeScript의 기본개념과 환경설정

TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)

JavaScript MVC 패턴으로 만드는 SPA cover image
JavaScript,  Design Pattern

JavaScript MVC 패턴으로 만드는 SPA

모던 JavaScript 프레임워크 없이 MVC 패턴으로 SPA을 만들어보자

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

노드 버전 매니저 툴 비교기(nvm & fnm & Volta) cover image
Tool,  Node.js

노드 버전 매니저 툴 비교기(nvm & fnm & Volta)

nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다.

다시 보기 위해 적어두는 URI 구조 cover image
Network,  URI

다시 보기 위해 적어두는 URI 구조

하나의 주소 안에도 여러가지 용어가 나온다. Host, Domain, Site, Origin등이 그것이다.

React의 클래스형, 함수형 컴포넌트 차이 cover image
React,  JavaScript

React의 클래스형, 함수형 컴포넌트 차이

react의 class, function 컴포넌트 차이 Class 컴포넌트 Class 컴포넌트로 Counter를 만들어보자. react 라이브러리에서 제공하는 Component를 import 받아와서 상속 관계를 맺어주었음. 따라서, react…

객체지향 프로그래밍으로 알아보는 prototype cover image
JavaScript

객체지향 프로그래밍으로 알아보는 prototype

자바스크립트가 만들어진 기반, prototype 언어가 가지는 근본적인 철학에 대해 고민해보자.

Event Loop와 비동기 cover image
JavaScript

Event Loop와 비동기

JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. await 키워드를 만나면 async가 붙은 함수 전체가 MicroTask Queue에 담기는 과정까지 알아보자.

JavaScript의 Symbol에 대해서. cover image
JavaScript

JavaScript의 Symbol에 대해서.

Symbol은 도대체 뭘까? 어디에 사용되고 있을까? 조금 더 깊게 들어가서 알아보자. 나중에 라이브러리를 만들 수도 있으니..

클로저와 함께 알아보는 curring 함수 cover image
JavaScript

클로저와 함께 알아보는 curring 함수

JavaScript의 클로저를 통해 currying 함수를 알아보자.

왜 내 z-index는 먹히지 않는가? cover image
CSS

왜 내 z-index는 먹히지 않는가?

z-index가 때로 적용이 되지 않는 문제를 해결하기 위해 stacking context에 대해 정확히 알아본다.

JavaScript에서 배열은 객체다 cover image
JavaScript

JavaScript에서 배열은 객체다

배열이 객체인 이유와, 유사 배열 객체와의 차이점을 알아본다.

JavaScript의 Getter / Setter cover image
JavaScript

JavaScript의 Getter / Setter

객체의 접근자 프로퍼티인 Getter와 Setter에 대해 알아보자.

JavaScript의 얕은 복사와 깊은 복사 cover image
JavaScript

JavaScript의 얕은 복사와 깊은 복사

JavaScript의 얕은 복사와 깊은 복사로 알아보는 객체의 특성. (feat. React, Vue.js)

nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기 cover image
Tool,  Node.js

nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기

NVM을 사용해 프로젝트 별로 Node.js 버전 지정을 자동화 해보자.

PDF 페이지 CSS로 안전하게 작성하기 cover image
CSS,  HTML,  PDF

PDF 페이지 CSS로 안전하게 작성하기

웹을 개발하다 보면, PDF로 문서를 사용자에게 제공하는 기능을 구현해야 할 때가 있다. 다른 개발자분들이 헤매지 않을 수 있도록 정리해보았다.

Tripllo 삭제 및 일상 회고 cover image
Tripllo 제작기,  Diary

Tripllo 삭제 및 일상 회고

정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif 파일도 모두 백업해두었다.

vue-meta와 Meta tag cover image
Vue.js,  HTML,  SEO

vue-meta와 Meta tag

Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자.

Semantic Web에 대해 더 깊이 알아보기 cover image
HTML,  SEO,  Semantic Web

Semantic Web에 대해 더 깊이 알아보기

Semantic Tag를 실제로 적용해보면서 고민했던 것과 팁을 함께 내용에 적어두었다. Semantic Tag에 대한 정의는 많지만 실제로 어떤 기준으로 적용해야할지 고민한다면 이 글이 도움이 될 수 있겠다.

블로그 탭 추가, 그리고 회고 시작 cover image
Blog,  Gatsby,  Diary

블로그 탭 추가, 그리고 회고 시작

주간회고를 시작하면서 블로그의 틀을 조금 수정했다.

(14) Closure & Currying 적용기 cover image
Tripllo 제작기,  JavaScript,  Vue.js

(14) Closure & Currying 적용기

함수형 프로그래밍에 대해서 공부하다가 Tripllo에 적용한 클로저와 커링.

(13) Vuex-store와 EventBus에 대한 고찰 cover image
Tripllo 제작기,  Vue.js

(13) Vuex-store와 EventBus에 대한 고찰

데이터를 Vuex store에 저장시키지 말고 로컬 컴포넌트에서 불러와 EventBus로 통신을 하면 어떻게 될까? 라는 물음에서 시작된 삽질기.

Vue2 반응성에 대해 깊이 알아보기 cover image
Vue.js

Vue2 반응성에 대해 깊이 알아보기

Vue 2.x 버전의 반응성에 대해 깊이 알아보자. Vue의 반응성을 제대로 알지 못한다면 UI 컴포넌트를 다룰 때, 혹은 data 객체를 다룰 때 문제가 생길 수 있다.

(12) Let's Encrypt 갱신 자동화 cover image
Tripllo 제작기,  Let's Encrypt,  Automation

(12) Let's Encrypt 갱신 자동화

AWS EC2 환경에서 Nginx와 Let's Encrypt로 HTTPS SSL 인증서 갱신 자동화를 해보자.

(11) Sentry 에러 로깅 시스템 도입 cover image
Tripllo 제작기,  Sentry,  Error

(11) Sentry 에러 로깅 시스템 도입

Sentry를 통해 프론트엔드 에러 로깅 시스템을 도입해보자.

(10) Frontend -travis 배포 자동화 cover image
Tripllo 제작기,  DevOps,  Automation

(10) Frontend -travis 배포 자동화

Vue프로젝트를 aws의 S3와 CloudFront에 Travis CI를 통해 배포 자동화를 해보자.

(9) vue 리팩토링2 cover image
Tripllo 제작기,  Refactoring,  Vue.js

(9) vue 리팩토링2

멘토링 후 Tripllo에 꽤 많은 것을 손봐야한다는 것을 알게 되었다. 하나하나 고쳐보면서 정리한 것을 기록해보자.

(8) vue 리팩토링1 cover image
Tripllo 제작기,  Refactoring,  Vue.js

(8) vue 리팩토링1

멘토링 후 Tripllo에 꽤 많은 것을 손봐야한다는 것을 알게 되었다. 하나하나 고쳐보면서 정리한 것을 기록해보자.

Gatsby 블로그 이사 cover image
Blog,  Gatsby,  Diary

Gatsby 블로그 이사

블로그 이사를 완료했다. 사실 블로그를 어떤 기준으로 운영해야하는지 감이 없기도 했고 개발 기록을 남기는 작업은, 첫 블로그를 만들기 전에 onenote에 전부 작업을 해두고 있었기 때문에 블로그에 전부 옮기는 작업이 귀찮기도 했었다. 하지만 어쨌든 블로그를 만들어뒀기 때문에 포트폴리오 프로젝트 정리를 약간 하는 용도로 사용했다.

Tripllo 후기 cover image
Tripllo 제작기

Tripllo 후기

프로젝트를 마무리했다. 두달 반 조금 안 되게 시간이 걸린 듯 하다. 프로젝트를 진행하면서 느꼈던 점을 조금 적어보려고 한다.

(7) 로그인4 -vue 소셜로그인 cover image
Tripllo 제작기,  Vue.js,  Social Login

(7) 로그인4 -vue 소셜로그인

vue에서 소셜 로그인 기능을 만들어보자. 보통 요즘 서비스들은 다 소셜 로그인으로 가입, 로그인이 되므로 앞으로 서비스 개발할 때 거의 필수적으로 들어갈 기능이라고 생각했다. 또 backend보다는 frontend 개발자로 지원하고 싶기 때문에 백엔드의 OAuth2.0 을 사용하는 것 보다는 Javascript단에서 로그인 기능을 넣고 싶었다.

(6) 로그인3 -vue 구현 cover image
Tripllo 제작기,  Vue.js

(6) 로그인3 -vue 구현

SpringBoot 쪽 서비스 로직이 만들어졌으므로 이번엔 vue에서 화면을 만들고 회원가입과 로그인을 진행해보자. 우리는 vue의 기능을 최대한 살려서 뼈대가 되는 페이지 하나에 login과 signup 2개의 컴포넌트를 붙이고 watch를 활용해 데이터를 검증할 것이다.

(5) 로그인2 -SpringBoot 구현 cover image
Tripllo 제작기,  SpringSecurity,  JWT

(5) 로그인2 -SpringBoot 구현

Spring Security와 JWT를 사용해서 로그인 기능을 구현했다. Spring Security의 구현된 소스와 login의 Service 단 내부 로직을 개념에 맞춰서 알아보자.

(4) 로그인1 -SpringSecurity & JWT 개념 cover image
Tripllo 제작기,  Spring Security,  JWT

(4) 로그인1 -SpringSecurity & JWT 개념

Spring Security와 JWT를 사용해서 로그인 기능을 구현했다. Spring Security와 JWT의 개념을 알아보자.

(3) Vue init & ESLint, Prettier 설정 cover image
Tripllo 제작기,  Vue.js

(3) Vue init & ESLint, Prettier 설정

백엔드 Setting은 끝났으니 이제 프론트엔드 Setting이 필요하다. npm 으로 Vue를 생성하고, 코드 포맷터인 ESLint, Prettier 설정을 해보자.

(2) MySQL 설계 & SpringBoot init cover image
Tripllo 제작기,  MySQL,  SpringBoot

(2) MySQL 설계 & SpringBoot init

Tripllo 백엔드 세팅을 해보자. Workbench로 DB를 설계하고 MySQL, MyBatis와 SpringBoot를 연동한다.

(1) 제작동기 cover image
Tripllo 제작기

(1) 제작동기

Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/4 정도 만들어진 상태로 배포되어 있다. 어플을 만들면서 다음번에 같은 문제를 만났을 때 참고할 만한 자료를 남겨두어야지 생각만 하다가 지금부터라도 남겨두어야겠다 싶어 제작기를 적으려고 한다.

오라클 CHR, ASCII 함수 사용법 cover image
Oracle

오라클 CHR, ASCII 함수 사용법

CHR(), ASCII() 함수 사용법.

오라클 테이블 스페이스 조작 cover image
Oracle

오라클 테이블 스페이스 조작

Local Oracle 사용시 용량에 문제가 생기면 이 방법을 사용하자.

ORACLE 계정관련 명령어 cover image
Oracle

ORACLE 계정관련 명령어

ORACLE 계정관련 명령어로 테이블 조작을 해보자.

Spring에서의 MediaType cover image
SpringBoot,  MediaType

Spring에서의 MediaType

Spring MVC에서 MediaType 매핑에 대해서 알아보고 테스트 해보자.

JUnit(2) - Mockito cover image
SpringBoot,  JUnit

JUnit(2) - Mockito

Mockito 프레임워크를 통해 Mock 테스트를 알아보자.

Github Blog에 카카오톡 공유버튼 만들기 cover image
Blog

Github Blog에 카카오톡 공유버튼 만들기

Jekyll로 만든 Github 블로그에 카톡 공유버튼을 만들어보자!

JUnit(1) - 개념 cover image
SpringBoot,  JUnit

JUnit(1) - 개념

SpringBoot에서 JUnit의 개념짚기.

Java 다형적 변수, 형변환 cover image
Java

Java 다형적 변수, 형변환

Java의 다형성을 통해 다형적 변수와 형변환에 대해서 알아보자.

+ );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Pozafly's Blog

기록 여정

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기

모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime) cover image
CSS,  Performance

모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)

전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기

ESLint로 import 구문에 규칙 넣기 cover image
Environment,  ESLint

ESLint로 import 구문에 규칙 넣기

규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.

GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys) cover image
DevOps,  GitHub Actions,  Automation

GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys)

restore-keys는 기존 캐시가 쓸모없어졌음에도 불구하고 기존 캐시를 불러오는 기능이다. 그렇다면, 무효화 되지 않은 캐시를 어디에 사용해야 하는 것일까?

Next.js의 API Routes 코드 모듈화에 대해서 cover image
Next.js

Next.js의 API Routes 코드 모듈화에 대해서

API Routes를 사용하면 코드가 매우 지저분해진다. API Routes를 사용하면서 어떻게 하면 코드를 보기 좋은 형태로 남길 수 있을지 고민한 흔적.

글또 8기 회고 cover image
Diary

글또 8기 회고

6개월 간 참여한 글또 활동 회고. 글쓰기에 대해서.

React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법 cover image
React-Query,  React

React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법

React Query의 mutation 실행 이후 클라이언트의 서버 데이터는 변경 되지 않은 상태이다. 화면을 업데이트 하는 여러 가지 방법을 알아보면서, 어떤 상황에서 어떤 방법을 사용해야 하는지 알아보자.

한영타변환기 Alfred Workflow 개발기 cover image
Tool,  Alfred,  Automation

한영타변환기 Alfred Workflow 개발기

dlfjgrp Tjwlseks akfdlek. dlrp sjan Qkrclseks akfdlek. zzzz...

React 렌더링과정으로 알아보는 선언적이라는 의미 cover image
React

React 렌더링과정으로 알아보는 선언적이라는 의미

React는 개발자에게 코드를 선언적으로 작성하도록 한다. 이것을 렌더링 과정과 ErrorBoundary를 통해 알아보자.

React는 Hooks를 배열로 관리하고 있다 cover image
React

React는 Hooks를 배열로 관리하고 있다

왜 Hooks에 이런 제약 조건을 걸었을까? React 내부에서 Hooks를 어떻게 처리하고 있는지, 이렇게 디자인 된 이유는 무엇인지 알아보자.

왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까? cover image
TypeScript

왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까?

TypeScript void 타입을 조금 더 알아보기.

TypeScript의 기본개념과 환경설정 cover image
TypeScript,  Environment

TypeScript의 기본개념과 환경설정

TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)

JavaScript MVC 패턴으로 만드는 SPA cover image
JavaScript,  Design Pattern

JavaScript MVC 패턴으로 만드는 SPA

모던 JavaScript 프레임워크 없이 MVC 패턴으로 SPA을 만들어보자

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

노드 버전 매니저 툴 비교기(nvm & fnm & Volta) cover image
Tool,  Node.js

노드 버전 매니저 툴 비교기(nvm & fnm & Volta)

nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다.

다시 보기 위해 적어두는 URI 구조 cover image
Network,  URI

다시 보기 위해 적어두는 URI 구조

하나의 주소 안에도 여러가지 용어가 나온다. Host, Domain, Site, Origin등이 그것이다.

React의 클래스형, 함수형 컴포넌트 차이 cover image
React,  JavaScript

React의 클래스형, 함수형 컴포넌트 차이

react의 class, function 컴포넌트 차이 Class 컴포넌트 Class 컴포넌트로 Counter를 만들어보자. react 라이브러리에서 제공하는 Component를 import 받아와서 상속 관계를 맺어주었음. 따라서, react…

객체지향 프로그래밍으로 알아보는 prototype cover image
JavaScript

객체지향 프로그래밍으로 알아보는 prototype

자바스크립트가 만들어진 기반, prototype 언어가 가지는 근본적인 철학에 대해 고민해보자.

Event Loop와 비동기 cover image
JavaScript

Event Loop와 비동기

JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. await 키워드를 만나면 async가 붙은 함수 전체가 MicroTask Queue에 담기는 과정까지 알아보자.

JavaScript의 Symbol에 대해서. cover image
JavaScript

JavaScript의 Symbol에 대해서.

Symbol은 도대체 뭘까? 어디에 사용되고 있을까? 조금 더 깊게 들어가서 알아보자. 나중에 라이브러리를 만들 수도 있으니..

클로저와 함께 알아보는 curring 함수 cover image
JavaScript

클로저와 함께 알아보는 curring 함수

JavaScript의 클로저를 통해 currying 함수를 알아보자.

왜 내 z-index는 먹히지 않는가? cover image
CSS

왜 내 z-index는 먹히지 않는가?

z-index가 때로 적용이 되지 않는 문제를 해결하기 위해 stacking context에 대해 정확히 알아본다.

JavaScript에서 배열은 객체다 cover image
JavaScript

JavaScript에서 배열은 객체다

배열이 객체인 이유와, 유사 배열 객체와의 차이점을 알아본다.

JavaScript의 Getter / Setter cover image
JavaScript

JavaScript의 Getter / Setter

객체의 접근자 프로퍼티인 Getter와 Setter에 대해 알아보자.

JavaScript의 얕은 복사와 깊은 복사 cover image
JavaScript

JavaScript의 얕은 복사와 깊은 복사

JavaScript의 얕은 복사와 깊은 복사로 알아보는 객체의 특성. (feat. React, Vue.js)

nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기 cover image
Tool,  Node.js

nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기

NVM을 사용해 프로젝트 별로 Node.js 버전 지정을 자동화 해보자.

PDF 페이지 CSS로 안전하게 작성하기 cover image
CSS,  HTML,  PDF

PDF 페이지 CSS로 안전하게 작성하기

웹을 개발하다 보면, PDF로 문서를 사용자에게 제공하는 기능을 구현해야 할 때가 있다. 다른 개발자분들이 헤매지 않을 수 있도록 정리해보았다.

Tripllo 삭제 및 일상 회고 cover image
Tripllo 제작기,  Diary

Tripllo 삭제 및 일상 회고

정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif 파일도 모두 백업해두었다.

vue-meta와 Meta tag cover image
Vue.js,  HTML,  SEO

vue-meta와 Meta tag

Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자.

Semantic Web에 대해 더 깊이 알아보기 cover image
HTML,  SEO,  Semantic Web

Semantic Web에 대해 더 깊이 알아보기

Semantic Tag를 실제로 적용해보면서 고민했던 것과 팁을 함께 내용에 적어두었다. Semantic Tag에 대한 정의는 많지만 실제로 어떤 기준으로 적용해야할지 고민한다면 이 글이 도움이 될 수 있겠다.

블로그 탭 추가, 그리고 회고 시작 cover image
Blog,  Gatsby,  Diary

블로그 탭 추가, 그리고 회고 시작

주간회고를 시작하면서 블로그의 틀을 조금 수정했다.

(14) Closure & Currying 적용기 cover image
Tripllo 제작기,  JavaScript,  Vue.js

(14) Closure & Currying 적용기

함수형 프로그래밍에 대해서 공부하다가 Tripllo에 적용한 클로저와 커링.

(13) Vuex-store와 EventBus에 대한 고찰 cover image
Tripllo 제작기,  Vue.js

(13) Vuex-store와 EventBus에 대한 고찰

데이터를 Vuex store에 저장시키지 말고 로컬 컴포넌트에서 불러와 EventBus로 통신을 하면 어떻게 될까? 라는 물음에서 시작된 삽질기.

Vue2 반응성에 대해 깊이 알아보기 cover image
Vue.js

Vue2 반응성에 대해 깊이 알아보기

Vue 2.x 버전의 반응성에 대해 깊이 알아보자. Vue의 반응성을 제대로 알지 못한다면 UI 컴포넌트를 다룰 때, 혹은 data 객체를 다룰 때 문제가 생길 수 있다.

(12) Let's Encrypt 갱신 자동화 cover image
Tripllo 제작기,  Let's Encrypt,  Automation

(12) Let's Encrypt 갱신 자동화

AWS EC2 환경에서 Nginx와 Let's Encrypt로 HTTPS SSL 인증서 갱신 자동화를 해보자.

(11) Sentry 에러 로깅 시스템 도입 cover image
Tripllo 제작기,  Sentry,  Error

(11) Sentry 에러 로깅 시스템 도입

Sentry를 통해 프론트엔드 에러 로깅 시스템을 도입해보자.

(10) Frontend -travis 배포 자동화 cover image
Tripllo 제작기,  DevOps,  Automation

(10) Frontend -travis 배포 자동화

Vue프로젝트를 aws의 S3와 CloudFront에 Travis CI를 통해 배포 자동화를 해보자.

(9) vue 리팩토링2 cover image
Tripllo 제작기,  Refactoring,  Vue.js

(9) vue 리팩토링2

멘토링 후 Tripllo에 꽤 많은 것을 손봐야한다는 것을 알게 되었다. 하나하나 고쳐보면서 정리한 것을 기록해보자.

(8) vue 리팩토링1 cover image
Tripllo 제작기,  Refactoring,  Vue.js

(8) vue 리팩토링1

멘토링 후 Tripllo에 꽤 많은 것을 손봐야한다는 것을 알게 되었다. 하나하나 고쳐보면서 정리한 것을 기록해보자.

Gatsby 블로그 이사 cover image
Blog,  Gatsby,  Diary

Gatsby 블로그 이사

블로그 이사를 완료했다. 사실 블로그를 어떤 기준으로 운영해야하는지 감이 없기도 했고 개발 기록을 남기는 작업은, 첫 블로그를 만들기 전에 onenote에 전부 작업을 해두고 있었기 때문에 블로그에 전부 옮기는 작업이 귀찮기도 했었다. 하지만 어쨌든 블로그를 만들어뒀기 때문에 포트폴리오 프로젝트 정리를 약간 하는 용도로 사용했다.

Tripllo 후기 cover image
Tripllo 제작기

Tripllo 후기

프로젝트를 마무리했다. 두달 반 조금 안 되게 시간이 걸린 듯 하다. 프로젝트를 진행하면서 느꼈던 점을 조금 적어보려고 한다.

(7) 로그인4 -vue 소셜로그인 cover image
Tripllo 제작기,  Vue.js,  Social Login

(7) 로그인4 -vue 소셜로그인

vue에서 소셜 로그인 기능을 만들어보자. 보통 요즘 서비스들은 다 소셜 로그인으로 가입, 로그인이 되므로 앞으로 서비스 개발할 때 거의 필수적으로 들어갈 기능이라고 생각했다. 또 backend보다는 frontend 개발자로 지원하고 싶기 때문에 백엔드의 OAuth2.0 을 사용하는 것 보다는 Javascript단에서 로그인 기능을 넣고 싶었다.

(6) 로그인3 -vue 구현 cover image
Tripllo 제작기,  Vue.js

(6) 로그인3 -vue 구현

SpringBoot 쪽 서비스 로직이 만들어졌으므로 이번엔 vue에서 화면을 만들고 회원가입과 로그인을 진행해보자. 우리는 vue의 기능을 최대한 살려서 뼈대가 되는 페이지 하나에 login과 signup 2개의 컴포넌트를 붙이고 watch를 활용해 데이터를 검증할 것이다.

(5) 로그인2 -SpringBoot 구현 cover image
Tripllo 제작기,  SpringSecurity,  JWT

(5) 로그인2 -SpringBoot 구현

Spring Security와 JWT를 사용해서 로그인 기능을 구현했다. Spring Security의 구현된 소스와 login의 Service 단 내부 로직을 개념에 맞춰서 알아보자.

(4) 로그인1 -SpringSecurity & JWT 개념 cover image
Tripllo 제작기,  Spring Security,  JWT

(4) 로그인1 -SpringSecurity & JWT 개념

Spring Security와 JWT를 사용해서 로그인 기능을 구현했다. Spring Security와 JWT의 개념을 알아보자.

(3) Vue init & ESLint, Prettier 설정 cover image
Tripllo 제작기,  Vue.js

(3) Vue init & ESLint, Prettier 설정

백엔드 Setting은 끝났으니 이제 프론트엔드 Setting이 필요하다. npm 으로 Vue를 생성하고, 코드 포맷터인 ESLint, Prettier 설정을 해보자.

(2) MySQL 설계 & SpringBoot init cover image
Tripllo 제작기,  MySQL,  SpringBoot

(2) MySQL 설계 & SpringBoot init

Tripllo 백엔드 세팅을 해보자. Workbench로 DB를 설계하고 MySQL, MyBatis와 SpringBoot를 연동한다.

(1) 제작동기 cover image
Tripllo 제작기

(1) 제작동기

Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/4 정도 만들어진 상태로 배포되어 있다. 어플을 만들면서 다음번에 같은 문제를 만났을 때 참고할 만한 자료를 남겨두어야지 생각만 하다가 지금부터라도 남겨두어야겠다 싶어 제작기를 적으려고 한다.

오라클 CHR, ASCII 함수 사용법 cover image
Oracle

오라클 CHR, ASCII 함수 사용법

CHR(), ASCII() 함수 사용법.

오라클 테이블 스페이스 조작 cover image
Oracle

오라클 테이블 스페이스 조작

Local Oracle 사용시 용량에 문제가 생기면 이 방법을 사용하자.

ORACLE 계정관련 명령어 cover image
Oracle

ORACLE 계정관련 명령어

ORACLE 계정관련 명령어로 테이블 조작을 해보자.

Spring에서의 MediaType cover image
SpringBoot,  MediaType

Spring에서의 MediaType

Spring MVC에서 MediaType 매핑에 대해서 알아보고 테스트 해보자.

JUnit(2) - Mockito cover image
SpringBoot,  JUnit

JUnit(2) - Mockito

Mockito 프레임워크를 통해 Mock 테스트를 알아보자.

Github Blog에 카카오톡 공유버튼 만들기 cover image
Blog

Github Blog에 카카오톡 공유버튼 만들기

Jekyll로 만든 Github 블로그에 카톡 공유버튼을 만들어보자!

JUnit(1) - 개념 cover image
SpringBoot,  JUnit

JUnit(1) - 개념

SpringBoot에서 JUnit의 개념짚기.

Java 다형적 변수, 형변환 cover image
Java

Java 다형적 변수, 형변환

Java의 다형성을 통해 다형적 변수와 형변환에 대해서 알아보자.

"}]},{"type":"text","value":" 코드가 실행되고, 어플리케이션이 실행된다. 렌더링이 종료되어 브라우저에 코드가 실행되고 난 후, 소스코드를 수정하면 재미있는 현상을 볼 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 432px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 87.03703703703702%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACOklEQVR42p2UaXLaQBCFuf818jM3sCshrthgY0CbDTIIIcACCbGDNrR8GZYK8RrbU9WaHvXozZt+3SokcYBsLJD6MF0EDIc2URyT5zlfGYXA3/DQn2FMwHZm6E2NKIr3wa+AFnaPKFgjPbj8aoEzC7nTVFrt9h7wLXsXMEu3eyBlAN7cx2i3xNVHLz5M0/RjDEN/hdJyuDBgOA3oWV0ajQaqqqIoCpIk/fVrtdo+9lZKCodAxmoVYHZcIYyP6zp4nodt20wmE7F297ZYLATzIePx+B2Gx1Myf0neLuN7Q64rt8iyjKZpDAaDTwkkGB4BhTCRfkMSbHCnM8aC2Xy1wg/DA+AzezGOB54YLqekzRvWfYOrnz+o/r5AKl3S1UW+ElGXoQ9xdLDtcY7Cgx8GYt6eckiakLUU4vNvbB9kJvcKS1GPvtFk3lBZ6ncEHZ2xUsVT6zjSrZhrzMQ+T6szb6ps2/e7MjgCbtZkukTSLLFxbcqlErXKDZos0bzTuBcK270eUvWWiohVyiWK52fIYn1ZLCIL9RdSRbAOT1fObZOk+J2oWWdYu8a6KjIXpzvVMhtdE21kkT12yfd28nfvc5EmJs4zUcI1SVfGn3noHZOqULkvykZtNOk/Ph727LrkFYHyV8smWLEVV44WU2zRJSMBZgsg13FOKv7PnjLckFoa8WpOx+xiGAY9kTfLsj75c/insOP6GcFsjGn194C7ot4BfqSHn7RekmbMxyOykUG8WWL1+pim+SXAPwOFExUaKwTeAAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"t-query-params","title":"","src":"/static/f3469240e5ba64dfdecd6a6fb1abfbe5/dc3b1/t-query-params.png","srcSet":["/static/f3469240e5ba64dfdecd6a6fb1abfbe5/dc3b1/t-query-params.png 432w"],"sizes":"(max-width: 432px) 100vw, 432px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"바로, 소스코드를 수정한 모듈에 쿼리 파라미터 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"t"}]},{"type":"text","value":" 가 새롭게 붙은 파일이 브라우저로 로드되어 새롭게 대체되는 현상이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/client.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"payload"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"switch"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"payload"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"type"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"case"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'update'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isFirstUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n window"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"location"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"reload"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" Promise"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n payload"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"updates"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"type "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'js-update'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" hmrClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// CSS 관련 HMR 소스코드 더 있음."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"socket을 브라우저에 등록하는 과정에서 message 이벤트가 일어나면 실행할 handleMessage 함수를 등록했다. 바로 그 함수가 실행되는데 JavaScript 함수이므로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"hmrClient.fetchUpdate()"}]},{"type":"text","value":" 함수가 실행된다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"hmrClient는 마찬가지로 Vite가 처음 브라우저로 넘어왔을 때 만들어진 인스턴스인데, 이는 아래와 같다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/client.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" hmrClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"HMRClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n timestamp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n explicitImportRequired"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"acceptedPathWithoutQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"split"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"?"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n base "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":"\n acceptedPathWithoutQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"slice"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"?"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"explicitImportRequired "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'import&'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"t="}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"timestamp"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"query "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"&"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이곳이 핵심이다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await import()"}]},{"type":"text","value":" 를 사용해 어떤 다른 모듈을 동적으로 불러오는 것을 볼 수 있다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"t="}]},{"type":"text","value":" 로 시작하는 쿼리 파라미터가 있으며, t에는 timestamp가 존재한다. dev-tools에서 봤던, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App.tsx?t=xxx"}]},{"type":"text","value":" 는 이것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"HMRClient class를 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/hmr.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"class"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"HMRClient"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"constructor"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"importUpdatedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" importUpdatedModule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"public"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" isSelfUpdate "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isSelfUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fn "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" qualifiedCallbacks"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"dep"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"dep "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" fetchedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"undefined"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"text","value":" 을 받는다. 이는 HMRClinet class를 생성할 때 받는 함수 자체를 말하는데, 결국 이게 실행되는 것은, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await imort()"}]},{"type":"text","value":" 동적 모듈을 가져오는 과정이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"결국 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@vite/client.ts"}]},{"type":"text","value":" 에 있던 socket의 addEventListener에 등록된 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"text","value":" 에서 넘겨받은 payload 안에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"update"}]},{"type":"text","value":" 객체가 들어있고, update 객체에서는 이것이 js인지 css인지 구분하는 값과, timestamp 값, query 등의 값이 들어있다. 즉, 이 정보는 모두 devServer에서 만들어주어 socket으로 브라우저로 전송되어 입력되며 동적 import를 통해 다시 수정된 파일을 devServer에서 다시 브라우저로 전송하는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이를 도식화 해보면 아래와 같다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1920px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 56.199999999999996%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMCBAYJ/8QAFAEBAAAAAAAAAAAAAAAAAAAAAv/aAAwDAQACEAMQAAAB7fN2tNGQsK//xAAZEAADAQEBAAAAAAAAAAAAAAABAgMEBRP/2gAIAQEAAQUCniS+ms8/Wy5zYzIBJmqpCaef/8QAHREAAQQDAQEAAAAAAAAAAAAAAQIDBBMREiIUEP/aAAgBAwEBPwGMkQ3b4gEV70CXdHFDvqGmJNjeqrxWjD2bOE9cj5//xAAdEQEAAgEFAQAAAAAAAAAAAAACAQMiBBARISMT/9oACAECAQE/Abm9QYF7V4NXwItU2E0ZeJL5iKsl5xhkuu52/8QAKRAAAgECAwcEAwAAAAAAAAAAAQIDBBIAESEFFCIxMkFREyMkM1Jhgf/aAAgBAQAGPwKm2vV0G7bVjiki9useqWJA0sajhkgppL4nuuMBZTJZzQNieiqZN5hdkZ0tkpswkySxLfDKsotkReJWF3I6G0/I9ISZn6SSmXbq1zy5418Ye0fk3Ux1Ovc+f5gcCDMsTkqjv+hj/8QAHRABAQACAgMBAAAAAAAAAAAAAREAITFBUWFxkf/aAAgBAQABPyGa8ACbNMprDWa8httA6GbSIRWwrhLpt3un8G8AYIjhTadnhMDkDt2KnZztPiTLY5gEbKgFgF9Gf//aAAwDAQACAAMAAAAQjM//xAAWEQEBAQAAAAAAAAAAAAAAAAABEQD/2gAIAQMBAT8QTL6BIqYXZUkqBjv/xAAYEQEAAwEAAAAAAAAAAAAAAAABABEhYf/aAAgBAgEBPxCg9fXMMH5gDpp//8QAGhABAQADAQEAAAAAAAAAAAAAAREAITFBUf/aAAgBAQABPxAV8uSCEoM9mID9AyJpyHRyag+cYCbnd4ApFWALONMQWvo4duPw1ACfz8Pi4GmFUUxu9wr5FQFgZ//Z'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"hmr-process","title":"","src":"/static/7cf438b0f3030e920cede70837548650/aaf92/hmr-process.jpg","srcSet":["/static/7cf438b0f3030e920cede70837548650/953fe/hmr-process.jpg 500w","/static/7cf438b0f3030e920cede70837548650/0a251/hmr-process.jpg 1000w","/static/7cf438b0f3030e920cede70837548650/aaf92/hmr-process.jpg 1920w"],"sizes":"(max-width: 1920px) 100vw, 1920px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite는 import.meta를 통해 모듈의 정보를 이용해 HMR를 구현했다. url을 통해 모듈의 경로와 메타 데이터를 활용해 socket를 세팅하고, 소스코드 변경이 일어나면 모든 모듈을 교체하는 것이 아니라 변경된 코드가 담긴 모듈만 동적 import를 통해 교체하는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"App.tsx에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 을 콘솔에 찍어보면"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1758px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 11.799999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaklEQVR42l2MzQrDIBgE8/4vV3rP2WLNJxr/qTq1lxB6GHZgl91EvVHPHaM0VizeGKzWhBAJMSIiOOdJKeH9udyRc+Y4BH9GWmuUXKi10ntnS+J5PXbcOixrnEKgfTpzzosxxpV3/+9/fAFV7ZqPzoibTgAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"import.meta.hot","title":"","src":"/static/a917e557116f09da5960c8a9995cadc2/cbcea/import.meta.hot.png","srcSet":["/static/a917e557116f09da5960c8a9995cadc2/0eb09/import.meta.hot.png 500w","/static/a917e557116f09da5960c8a9995cadc2/1263b/import.meta.hot.png 1000w","/static/a917e557116f09da5960c8a9995cadc2/cbcea/import.meta.hot.png 1758w"],"sizes":"(max-width: 1758px) 100vw, 1758px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 정보를 가지고 있고, 그중 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"hotModulesMap"}]},{"type":"text","value":" 도 들어있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 806px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 28.599999999999998%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA+UlEQVR42pVR12rEMBD0//9Z3nLE4CrccJFLXOUqe+LdcBfyFCIYVit2htmRUQcZsjcb8l1APgSqjwClLBHFMfq+x3+PoSaFKivQlBWqW6itP7HMC+Z5xr7vOI6DQf22bdBaM/G6rl9Cz97Q14lCxLdQgzTLkKYpXNeF53lIkgR5nnO1bZvfuq57iY/jyP00TT8O9alRJwX6toOUEkVRIAgCmKYJIQSiKILjOK/q+z7jOUcIw5C5bdt+OyyDlFfN7yFyY1kWD5HbpmlYgMTJ7bquUEoxyCWtSnUYBnZu0MPS9BjaEYPacN4ZEYlyo7zO8+QsiUT3vz7lC76EyZDe5Ux1AAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"hotModulesMap","title":"","src":"/static/23b60f30ed3e8c840519669b599d7294/30577/hotModulesMap.png","srcSet":["/static/23b60f30ed3e8c840519669b599d7294/0eb09/hotModulesMap.png 500w","/static/23b60f30ed3e8c840519669b599d7294/30577/hotModulesMap.png 806w"],"sizes":"(max-width: 806px) 100vw, 806px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"hotModulesMap은, 현재 소스코드를 Vite가 code splitting을 통해 모듈로 나눠놓은 것을 담고 있다. 이 모듈에서 socket으로부터 받은 payload의 정보를 통해 모듈을 교체하기 때문에 훨씬 효율적으로 모듈을 교체할 수 있는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"참고로, .env 파일의 환경 변수를 담는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.env"}]},{"type":"text","value":" 와 HMR의 모듈 교체를 위한 map을 담고 있는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 는 브라우저로 전송되는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".tsx"}]},{"type":"text","value":" 모든 모듈의 상단에서 주입하고 있다. 위에서 봤던 사진을 다시 한번 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1170px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 33.599999999999994%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABSUlEQVR42pWR0XKjMAxF+f+P6g/sbLJMkpIEkqbBBbKACSUp2MacikwfOn3ZWc3ckWRdXcty8PRLESU5iz8btvGZaHdiGUZsoiP7g+L38pnk+Ea42j3Ok6Nitd5L/cDL+cIi3BKu4wd3tUkI1nHB8tATHRsqfRd8cCk7LlWHllhfB+rWUDU9RSU1PVDo/sHTsy/fKQWV8Of+oHcTXXWnXWWkrzJtHJOmKSrPuaicIi+JT2+c0oLkVJCrkuw1o5Xaragw1wbTtgxNgx0GgnGC0ThsVlNsd+Txnrau6XWNsxbrHMYYnLN478CPTBJPo5Pc89MCJ4qiiX1vuYZLbirlI1Pc0zO26/inTXP39OW/C7az4EKeWnNWf2VsJ1OM/K8Fo0xtjMV0N6zW1Ne7fEKPcZ5BYL8wmJHBekaBF76XdXhZx+znix+5NXwCIv4VyibLESYAAAAASUVORK5CYII='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"source-tab","title":"","src":"/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png","srcSet":["/static/79da4e50c599e0226c48d5439368c947/0eb09/source-tab.png 500w","/static/79da4e50c599e0226c48d5439368c947/1263b/source-tab.png 1000w","/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png 1170w"],"sizes":"(max-width: 1170px) 100vw, 1170px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"그래서, 소스코드를 수정할 때마다 새로운 timestamp가 쿼리 파라미터가 브라우저에 넘어오고, 쿼리 파라미터 정보를 import.meta로 읽어 새로운 모듈을 가져와야 한다는 정보를 얻어 devServer에 요청 후 갈아끼울 수 있는 매커니즘을 가질 수 있었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"그렇다면, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await import()"}]},{"type":"text","value":" 동적 가져오기를 사용해 모듈 자체(예시: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Some.tsx"}]},{"type":"text","value":") 가져왔다면 react에서 적용은 어떻게 하는 것일까? HMRClient class의 fetchUpdate() 함수를 다시 가져왔다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/hmr.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"public"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" isSelfUpdate "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isSelfUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fn "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" qualifiedCallbacks"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"dep"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"dep "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" fetchedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"undefined"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"qualifiedCallbacks"}]},{"type":"text","value":" 은 허용된 콜백이라는 뜻인데, 허용된 목록 안에 있는 acceptedPath가 모듈 path(dep) 와 동일하다면 fn을 실행하는 구조로 되어있다. 외부로 노출된 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 을 통해 콜백이 허용되었는지를 검사 후, 모듈을 교체하는 작업이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이후의 동작은 Vite 공식 문서의 "},{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/features.html#hot-module-replacement","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"Hot Module Replacement"}]},{"type":"text","value":"를 통해 사용하고 있는 프레임워크의 plugin으로 이어져 동작하게 된다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"마이그레이션-결과","style":"position:relative;"},"children":[{"type":"text","value":"마이그레이션 결과"},{"type":"element","tagName":"a","properties":{"href":"#%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EA%B2%B0%EA%B3%BC","ariaLabel":"마이그레이션 결과 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"vue-cli를 Vite로 마이그레이션 한 결과 devServer 실행 속도뿐 아니라 build 속도도 개선되었다. 아래는 GitHub Actions 빌드 결과이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"vue-cli 빌드 결과"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1136px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 9%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaklEQVR42i2NSxKAIAxDHRUURFrBH+rC+18y1uriTdJJJ6mWcoNywbRciGkXNpDoQDN4Lhh5lexUrCNYzx+/N68Kpo96V0mK/Ji10IcJdWPQtPZT06nvfJTyA+7/o1R0nPMhGSPQCheyjj6w4i7DTW5HkgAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"vue-cli-build","title":"","src":"/static/a261ab9d1208dfc27795f784d951b073/46e29/vue-cli-build.png","srcSet":["/static/a261ab9d1208dfc27795f784d951b073/0eb09/vue-cli-build.png 500w","/static/a261ab9d1208dfc27795f784d951b073/1263b/vue-cli-build.png 1000w","/static/a261ab9d1208dfc27795f784d951b073/46e29/vue-cli-build.png 1136w"],"sizes":"(max-width: 1136px) 100vw, 1136px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Vite 빌드 결과"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 332px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 15.36144578313253%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAoklEQVR42jVO2wqCQBRUd921495kV5OEfJGICoIgqB/o//9oWo/4MAwzcy5TCGVQN45R1S1KSSgFodJt1sRaNAaCLMqsK7X5e76yIMO8zhZkE66PNy63F6TOS4qgh44RvzPCc4K9jPD3E6S1MMuQ9RE0J+bDFDH+FsTPmYsUUju0vge5tDXcW+SPug8M6RyksezV3vFh0VqoznOmU4CKgRv+AUAjRTsUTpctAAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"vite-build","title":"","src":"/static/14daa32896955b7dc7db07782d7f4057/557e0/vite-build.png","srcSet":["/static/14daa32896955b7dc7db07782d7f4057/557e0/vite-build.png 332w"],"sizes":"(max-width: 332px) 100vw, 332px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"14s → 5s로 약 62% build 속도가 증가되었다. Vite는 내부적으로 빌드 시 rollup을 사용하기 때문에 Webpack에 비해 더욱 빠른 속도로 빌드 할 수 있다. (devServer는 esbuild로 번들링)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"마치며","style":"position:relative;"},"children":[{"type":"text","value":"마치며"},{"type":"element","tagName":"a","properties":{"href":"#%EB%A7%88%EC%B9%98%EB%A9%B0","ariaLabel":"마치며 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"import.meta는 모듈의 메타 데이터를 저장하고, 활용할 수 있는 도구다. 이전에 import.meta가 없었을 때는 Node.js 환경에서 아래 코드와 같이 파일의 경로를 알아내고, 파일을 읽어올 수 있었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Node.js 환경"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" fs "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'fs'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'path'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" bytes "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" fs"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"readFileSync"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__dirname"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'data.bin'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"또한, 브라우저 환경에서 모듈에 대한 메타 데이터를 얻을 수 있는 방법은 아래와 같았다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"html"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":""}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"data-option"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"src"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"library.js"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","language-javascript"]},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" theOption "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"currentScript"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"dataset"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"option"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"하지만, Node.js 환경에서는 fs와 path 라이브러리를 항상 가지고 있어야 하며, 브라우저 환경에서는 현재 실행되고 있는 스크립트가 반드시 library.js 모듈일지는 불명확했기 때문에 문제가 되었다. 따라서 TC39에 import.meta에 대한 제안이 올라왔고 구현되었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"import.meta는 비교적 최신 문법이며, 따라서 구형 브라우저에서는 동작하지 않는다. Vite는 import.meta를 사용하기 때문에 자연스럽게 "},{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/#browser-support","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"구형 브라우저에서는 사용할 수 없다"}]},{"type":"text","value":". 하지만, "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/vitejs/vite/tree/main/packages/plugin-legacy","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"@vitejs/plugin-legacy"}]},{"type":"text","value":"를 사용한다면 가능하다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"또한, Vite의 "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/vitejs/vite/discussions/8132","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"discussions"}]},{"type":"text","value":"를 보면 process.env 대신 import.meta를 사용하는 이유에 대한 답변으로 ECMAScript 모듈의 ‘새로운’ 표준이기 때문에 사용한다라는 답변이 있다. 물론 import.meta는 ECMAScript의 새로운 표준이기도 하지만 Vite가 개발 모드에서 브라우저에 모듈을 서빙하는 과정을 보면 브라우저 자체가 모듈을 다룰 수 있도록 하고, 빠른 번들링 및 모듈 교체를 위함임을 알 수 있다. 이는 Vite의 철학과도 연관되어 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite로 마이그레이션 하면서 process.env대신, import.meta를 사용하는 이유가 궁금했다. 결과, import.meta MDN 문서도 함께 번역해 보면서 번들러가 어떻게 이를 사용하고 있는지 살펴볼 수 있는 시간이었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"참고"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://www.proposals.es/proposals/import.meta","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"import.meta proposals"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://dmitripavlutin.com/javascript-import-meta/","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"How to Access ES Module Metadata using import.meta"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/import.meta","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"MDN - import.meta"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"Vite"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]}],"data":{"quirksMode":false}},"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","fields":{"readingTime":{"text":"15 min read"}},"frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","userDate":"4 February 2024","date":"2024-02-04","tags":["Bundler","Vite","Environment"],"excerpt":"Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.","photoAuthor":"Voicu Apostol>>https://unsplash.com/ko/@cerpow>>true","photoVender":"Unsplash>>https://unsplash.com","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/ba386/main.avif 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/8adb1/main.avif 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/dc6b3/main.avif 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}},"author":[{"name":"Pozafly","bio":"Frontend Developer","avatar":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#6808f8","images":{"fallback":{"src":"/static/8c061761f263c344f2c0416607c8adf1/73bb6/pozafly.jpg","srcSet":"/static/8c061761f263c344f2c0416607c8adf1/2f28c/pozafly.jpg 40w,\n/static/8c061761f263c344f2c0416607c8adf1/499f6/pozafly.jpg 80w,\n/static/8c061761f263c344f2c0416607c8adf1/73bb6/pozafly.jpg 120w","sizes":"100vw"},"sources":[{"srcSet":"/static/8c061761f263c344f2c0416607c8adf1/e73fe/pozafly.webp 40w,\n/static/8c061761f263c344f2c0416607c8adf1/61ca6/pozafly.webp 80w,\n/static/8c061761f263c344f2c0416607c8adf1/507b0/pozafly.webp 120w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":1}}}}]}},"relatedPosts":{"totalCount":2,"edges":[{"node":{"id":"e6258425-92a4-5f5c-8e75-b7cd70515731","excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","date":"2024-02-04"},"fields":{"readingTime":{"text":"15 min read"},"slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"id":"9257b05f-542a-5347-bbdb-81575de93244","excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","date":"2023-04-05"},"fields":{"readingTime":{"text":"33 min read"},"slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"slug":"/environment/why-do-you-use-import-meta-in-vite/","prev":null,"next":{"excerpt":"모던 웹 개발 생태계에서 CSS를 제작할 수 있는 다양한 방법이 있다. JavaScript 웹 프레임워크 분야는 거의 React가 대부분을 차지하고 있다. CSS 프레임워크(혹은 라이브러리)도 React의 영향 때문인지, 프로덕션에 CSS-in-JS…","frontmatter":{"title":"모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)","tags":["CSS","Performance"],"date":"2023-10-08","draft":false,"photoAuthor":"Michael Dziedzic>>https://unsplash.com/ko/@lazycreekimages","photoVender":"Unsplash>>https://unsplash.com","excerpt":"전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcICf/EABYBAQEBAAAAAAAAAAAAAAAAAAcFBv/aAAwDAQACEAMQAAABzEbqqcjgEzGUiQ81/8QAGxAAAgMAAwAAAAAAAAAAAAAAAwQBAgUABhL/2gAIAQEAAQUCxknXz9owKIt3G7M4qg+Ux0byVQPv/8QAIBEAAgICAQUBAAAAAAAAAAAAAQMCBAURBgASExRBFf/aAAgBAwEBPwG7zfA4q1mq17CLs17SV/k+CrX9jHXFrmJFtizKc7FWw6QmyCvVmpY8aj36cI80UYgjHpAI2BonQ+Df3XX/xAAeEQACAQQDAQAAAAAAAAAAAAABAgMABBESBQcT0v/aAAgBAgEBPwGXsqOBbbI5L3gkk9ljuFFvdwyLgKQVzA8R1ZH1udmU5ARylHs7kSc/Vf/EACQQAAICAQQBBAMAAAAAAAAAAAECAwQRAAUSITETInGBIzKR/9oACAEBAAY/AvSqSQGNVRpnss4WBGfgH/GGlcA5J4KcAd4yud5bZDfu7FtNmnSfdrZpx5t3IJLMUMccEhEqmsi2OQGYlkCWMPxL5HuB7Vs+QfB+9IcsGHhlZkYZ84ZGDD6PevVkjaWQjszSzS5+VeQqfgrjX6j+a//EABsQAQADAAMBAAAAAAAAAAAAAAEAESExQWGx/9oACAEBAAE/IaMOOpmZAB69oRT4BXgPmEc0tR9GAVbgzgUktD4w6aydgHYYuzq14YFmi0KixqEQABQUoCzPPk//2gAMAwEAAgADAAAAEMf/AP/EABcRAQEBAQAAAAAAAAAAAAAAAAERIQD/2gAIAQMBAT8QYd7v3iIPcXvQl/FoXUCUGLCpYXP/xAAaEQEBAAIDAAAAAAAAAAAAAAABESFRADFB/9oACAECAQE/EGRoZHE3Y+FAzoIlbLhUZca7hvzn/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAMUFh/9oACAEBAAE/EJsiZVLs8ZmdBLO3H/FAjzDjRSuUq/7vxJ3qkLHEcQSkA1AEAyvkA0MofXmFwxmYANAAEAAAAAgAAb//2Q=="},"images":{"fallback":{"src":"/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg","srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/6cce3/main.jpg 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/dec99/main.jpg 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/12c41/main.jpg 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/d2a19/main.webp 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/39bea/main.webp 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/8f28c/main.webp 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/237ec/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6682291666666667}}}},"fields":{"readingTime":{"text":"29 min read"},"layout":"post","slug":"/css/explore-how-to-apply-modern-css/"}},"primaryTag":"Bundler"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file +{"componentChunkName":"component---src-templates-post-tsx","path":"/environment/why-do-you-use-import-meta-in-vite/","result":{"data":{"markdownRemark":{"html":"

회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 패키지 내부에는 eslint, prettier가 vue-cli에 맞게 묶여있었는데 최신 버전의 eslint, prettier 버전을 사용하고 싶어도 호환이 되지 않았다. 그래서 vue-cli 대신 번들러를 바꿔 개발 환경을 최신화하기로 했다.

\n

예전부터 사용해 보고 싶었던 번들러는 Vite다. Vite의 가장 큰 특징은 devServer에서 소스코드와 디펜던시를 두 가지 카테고리로 나누어 빌드하고, ESM 환경인, 브라우저에 빠르게 제공한다는 점이다. devServer가 cold-start 될 때 현재 페이지에서 필요한 정보만 아주 빠르게 실행시킬 수 있다. 이 말은, 코드 베이스 또는 라이브러리(사용하고 있는 node_modules 디펜던시)의 모든 파일을 번들링 하여 제공하는 것이 아니라, 현재 필요한 모듈만 골라내어 빠르게 제공한다는 뜻이다. Vite 가이드에서 가장 먼저 이야기하고 있는 것이 ESM을 통한 devServer start 속도이다.

\n

사전 번들링은, esBuild를 통해 디펜던시를 빌드하고, 변경이 잦은 소스코드는 ESM으로 제공한다. 기존에 Webpack과 같은 번들러는 모든 파일을 빌드 및 번들링 해야만 브라우저에서 구동이 가능했다. Vite는 소스코드를 ESM으로 제공하기 때문에 브라우저에서 동적 import를 통해 원하는 JavaScript 파일만 실행시킬 수 있다. 이 매커니즘에 따라 Webpack의 Node.js에서만 가능했던 기능이 브라우저에서 동작하기 위해 어떻게 Vite가 해결했는지를 알아볼 것이다.

\n
\n

Node.js 환경 변수

\n

process.env

\n

대부분의 bundler는 Node.js 환경 위에서 동작한다. Node.js에서는 process 라는 특별한 이름의 예약어를 사용해 환경 변수에 접근할 수 있다. process 예약어는 현재 실행되고 있는 Node.js 프로세스에 대한 정보를 가지고 있고 이를 제어할 수 있는 객체다.

\n

대부분의 JavaScript 프레임워크에서는 process.env 변수를 통해 환경 변수에 접근한다. process.env는 런타임에 동적으로 변수를 추가 및 수정할 수 있다.

\n
console.log(process.env.TEST); // undefined\nprocess.env.TEST = \"test!\";\nconsole.log(process.env.TEST); // test!
\n

위 코드를 Node.js의 node 명령어로 실행하면 주석과 같은 결과를 얻을 수 있다. 프레임워크에서는 .env 파일을 통해 process.env 변수에 개발자가 설정한 변수를 process.env에 주입시켜주는데, 주로 dotenv 라이브러리를 통해 주입한다.

\n

dotenv

\n

모던 JavaScript 프레임워크에서 dotenv 라는 라이브러리를 내부적으로 래핑해서 사용하고 있다. dotenv 라이브러리는 node.js 환경 및 ESM 환경에서 .env 파일에 있는 환경 변수를 런타임 환경의 JavaScript로 들고 올 수 있다.

\n

라이브러리를 가볍게 분석해 보자.

\n
$ npm init -y\n$ npm i -D dotenv
\n

명령어로 npm 환경을 생성한다. package.json 파일이 생성된 후, dotenv 라이브러리를 다운로드 받았다.

\n

프로젝트 root에 .env 파일을 생성하고 테스트 값을 넣는다.

\n
# .env file\nTEST=ENV_TEST!
\n

main.js 파일을 생성하고, dotenv 라이브러리를 통해 .env 파일의 환경 변수 값을 가져와보자.

\n
// src/main.js\n\nrequire(\"dotenv\").config();\nconsole.log(process.env.TEST);  // ENV_TEST!
\n

이제 node 명령어로 Node.js 환경에서 이를 실행시켜보자.

\n
$ node src/main.js\n\n=> ENV_TEST!
\n

어떻게 이런 결과가 나올까? dotenv 라이브러리를 살짝 까보자. 시작은 require(\"dotenv\").config(); 줄이다. config 메서드를 실행한다.

\n
function config (options) {\n  if (_dotenvKey(options).length === 0) {\n    return DotenvModule.configDotenv(options);\n  }\n  // ...\n}
\n

configDotenv() 함수를 실행한다. lib/main.js의 configDotenv 함수. .env 파일의 경로를 읽고 파싱 해 process 환경을 파싱 된 값으로 채우고 반환한다.

\n
function configDotenv (options) {\n  let dotenvPath = path.resolve(process.cwd(), '.env');\n  // ...\n  const parsed = DotenvModule.parse(fs.readFileSync(dotenvPath, { encoding }));\n\n  let processEnv = process.env;\n  if (options && options.processEnv != null) {\n    processEnv = options.processEnv;\n  }\n\n  DotenvModule.populate(processEnv, parsed, options);\n  return { parsed };\n}
\n
    \n
  1. \n

    dotenvPath 변수에 .env 파일의 경로를 저장한다.

    \n
      \n
    • process.cwd() : node 명령을 호출한 디렉토리의 절대 경로다. /Users/pozafly/Documents/dev/play-ground/dotenv-exam
    • \n
    • path.resolve() : 경로를 묶어 새로운 경로를 반환한다. /Users/pozafly/Documents/dev/play-ground/dotenv-exam/.env
    • \n
    \n
  2. \n
  3. \n

    parsed 변수에 .env 파일을 파싱 해 담는다.

    \n
      \n
    • \n

      fs.readFileSync() : 인자로 들어오는 절대 경로로 파일 text 값을 읽어온다. 따라서, dotenvPath의 값을 읽어온다.

      \n
    • \n
    • \n

      DotenvModule.parse() : 파싱 한 text 값을 JavaScript object로 만들어서 return 한다.

      \n
    • \n
    • \n

      parsed: { TEST: 'ENV_TEST!' } 값이 담겨있다.

      \n
    • \n
    \n
  4. \n
  5. \n

    populate(processEnv, parsed, options) 실행한다. populate는 ‘덧붙이다’라는 뜻을 가지고 있다.

    \n
  6. \n
\n
function populate (processEnv, parsed, options = {}) {\n  // Set process.env\n  for (const key of Object.keys(parsed)) {\n    // ...\n    processEnv[key] = parsed[key];\n  }\n}
\n

위에서 processEnv = process.env 로 레퍼런스 주소를 묶어주었기 때문에 key로 즉시 할당한다. 다시 우리가 작성했던 main.js 구문을 보자.

\n
require('dotenv').config();\nconsole.log(process.env.TEST);  // ENV_TEST!
\n

정리하면, dotenv 라이브러리는 Node.js 환경에서 .env 를 파싱 해 text 값을 통해 객체를 생성하고, process.env에 값을 추가해 Node.js 환경의 전역에 노출된다. JavaScript 프레임워크에서는 보통 Node.js를 한 번만 실행하기 때문에 .env 파일의 환경 변수 값이 변경되면 devServer를 껐다 켜주어야 값을 변경된 값으로 반영할 수 있는 이유이다.

\n

Vite는 바로 반영이 되는데, devServer를 순간적으로 다시 시작시켜준다. .env 파일에서 변수를 변경하면 터미널 log에 server restarted.라고 알려준다. Vite는 Webpack처럼 모든 파일을 번들링 하지 않기 때문에 무척 빠르기에 가능하다.

\n

dotenv에서 ESM 환경 또한 지원한다.

\n
// package.json\n{\n  \"type\": \"module\",\n}
\n

위와 같이 package.json 파일에 type을 module로 넣어주면 Node.js에서 ESM 코드를 사용할 수 있다.

\n
\n

※ Vite로 마이그레이션을 진행할 때도, package.json에 위와 같이 \"type\": \"module\" 을 넣어주어야 하는데, Vite는 기본적으로 ESM 방식으로 동작한다.

\n
\n

참고고, main.js 파일을, main.mjs 라는 확장자를 붙여주면 Node.js에서 알아서 ESM으로 동작하게 되기 때문에 package.json에 따로 붙여줄 필요는 없다.

\n

vue-cli는 @vue/cli-services 패키지 내에서 사용하고 있고, CRA 같은 경우 react-scripts 라이브러리 내부 package.json에 dotenv 을 사용하고 있으며 Next.js도 내부적으로 dotenv 라이브러리를 이용해 .env 파일을 가져오고 있다.

\n
\n

—env-file

\n

node.js 20 버전부터는 --env-file=config 를 통해 .env 파일을 dotenv 라이브러리 없이 사용할 수 있도록 개발 중이다. 실제로 터미널에서 node 명령어로 .env 파일을 지정 해 줄 수 있다. 아직은 실험용.

\n
$ node --env-file=.env --env-file=.development.env index.js
\n
// .env\nPORT=3000
\n

따라서, 이제는 점차 dotenv 라이브러리가 필요없어지게 될 것 같다.

\n
\n
\n

모드 별 환경 변수 접근

\n

하지만, .env 파일만 있는 것이 아니라 배포 환경에 따라 환경 변수의 값이 달라져야 환경 변수를 사용하는 의미가 있다. 즉, .env.development, .env.production 등의 환경 변수 파일이 추가로 필요하고 mode에 따라 지정된 값이 process.env 값에 할당되어 build 되어야 한다.

\n

dotenv-webpack 플러그인은 아주 간단하게 직접 path를 지정하도록 되어 있다.

\n

먼저 사용법을 보자.

\n
// webpack.config.js\n\nconst Dotenv = require('dotenv-webpack');\n\nmodule.exports = {\n  plugins: [\n    new Dotenv({ path: '.env.production' }),\n  ],\n};
\n

webpack 설정 파일에 new Dotenv() 를 통해 인스턴스를 만든다. 인자로 path key를 가진 객체를 넣어주는데, 빌드 시 적용할 .env.production 파일의 경로를 적어준다. 그럼, dotenv-webpack 플러그인을 보자. dotenv-webpack 소스

\n
import dotenv from 'dotenv-defaults';\n\nclass Dotenv {\n  // 1.\n  constructor (config = {}) {\n    this.config = Object.assign({}, {\n      path: './.env',\n      prefix: 'process.env.'\n    }, config);\n  }\n  \n  // 3.\n  getEnvs () {\n    const { path } = this.config;\n    const env = dotenv.parse(this.loadFile({\n      file: path,\n    }));\n    return {\n      env\n    };\n  }\n  \n  gatherVariables () {\n    const { env } = this.getEnvs(); // 2.\n    const vars = Object.assign({}, process.env); // 4.\n\n    Object.keys(env).forEach(key => {\n      const value = Object.prototype.hasOwnProperty.call(vars, key) ? vars[key] : env[key];\n      vars[key] = value; // 5.\n    })\n\n    return vars;\n  }\n}
\n

간추린 코드만 들고 왔다.

\n
    \n
  1. 인스턴스를 생성할 때, 넣어준 path를 생성자에서 설정한다.
  2. \n
  3. getEnvs() 메서드 실행.
  4. \n
  5. config에 담긴 path를 가져와 .env* 파일을 가져오고, dotenv 라이브러리에 parse 메서드를 사용해 env 객체로 만들어 return.
  6. \n
  7. vars 에 새로운 객체에다가 process.env 값을 복사한다.
  8. \n
  9. vars[key] = value 를 통해 파싱 한 값을 집어넣어 return.
  10. \n
\n

즉, dotenv-webpack은 단순히 .env 값을 path로 받아 파싱 한다.

\n
\n

Vite의 환경 변수 접근

\n

Vite는 환경 변수가 정의된 파일(.env)에서 여타 번들러와 마찬가지로 어플리케이션에 필요한 변수를 가져와 사용할 수 있다. Vite의 경우 공식 문서에서 환경 변수 접근법에 대해 import.meta라는 JavaScript 문법으로 접근할 것을 알려주고 있다. .env 파일에 환경과 관련된 변수를 VITE_ prefix를 주고, 코드 상에서 import.meta.env 로 선언한 값을 들고 올 수 있다.

\n

import.meta

\n

import.meta라는 JavaScript 문법을 알아보며 MDN 문서에 아직 아무도 번역하지 않아 이번 기회에 함께 번역해 보았다. import.meta 는 ES Module이 탄생하면서 모듈에 대한 메타 데이터(부수 데이터)를 저장하기 위한 객체다.

\n

여기서 말하는 메타 데이터란, 이미지 파일을 생각하면 조금 더 이해하기 쉽다. 휴대폰으로 사진을 찍으면 사진의 메타 데이터에 ‘날짜’, ‘사진 용량’, ‘디바이스 정보’, ‘위치 데이터’ 등의 메타 데이터가 담기게 된다. import.meta 는 ‘모듈’ 자체에 대한 메타 데이터를 담고 있다.

\n

import.meta는 대표적으로 모듈 메타 데이터인 경로(URL)를 담고 있는데, 이는 호스트 환경(브라우저 혹은 Node.js)에 따라 저장되는 내용이 달라진다. 먼저 Node.js를 통해 import.meta가 가지고 있는 정보를 열어보자.

\n
// src/main.js\n\nconsole.log(import.meta);
\n

node 명령어로 main.js를 실행시키면 SyntaxError가 발생한다. 이유는, node.js는 기본적으로 CommonJS 환경에서 동작하기 때문이다. import.meta는 ESM 환경에서 동작하기 때문에 이런 에러가 발생하는 것이다.

\n

Node.js에서 import.meta를 사용하는 방법은 2가지인데, 하나는 main.js 파일을 main.mjs 로 ESM에서 동작하는 JavaScript 확장자를 붙여주어 node 명령어로 다시 실행시키는 방법이고, 다른 하나는 dotenv 라이브러리에서 ESM 환경으로 동작시킬 때 알아본 package.json 파일에 \"type\": \"module\" 을 명시해 주는 방법이다.

\n
// src/main.js\n\nconsole.log(import.meta);\n/**\n * [Object: null prototype] {\n *   dirname: '/Users/pozafly/Documents/dev/play-ground/esm-exam/src',\n *   filename: '/Users/pozafly/Documents/dev/play-ground/esm-exam/src/main.js',\n *   resolve: [Function: resolve],\n *   url: 'file:///Users/pozafly/Documents/dev/play-ground/esm-exam/src/main.js'\n * }\n*/
\n

위와 같은 결과를 얻었다. dirname, filename, resolve, url 등의 정보가 들어있다. 절대 경로로 내 파일(모듈)의 위치를 가리키고 있다. 그렇다면 브라우저에서는 어떻게 동작하는가?

\n

간단하게 lite-server를 설치하고 index.html 파일을 브라우저로 서빙해보자.

\n
$ npm i -D lite-server
\n
// package.json\n{\n  // ...\n  \"type\": \"module\",\n  \"scripts\": {\n    \"dev\": \"lite-server\"\n  },\n  \"devDependencies\": {\n    \"lite-server\": \"^2.6.1\"\n  }\n}\n
\n

dev 스크립트를 입력해 주고, index.html 파일을 만들어 npm run dev 명령어를 실행한다.

\n
<!-- index.html -->\n<!DOCTYPE html>\n<html>\n  <head>\n    <script type=\"module\" src=\"./src/main.js\"></script>\n  </head>\n  <body></body>\n</html>
\n

\n \n \n

\n

이렇게 url의 모습이 변경된 것을 볼 수 있다. 그러면 이 url 변수를 가공해 info 값을 얻을 수가 있는데,

\n
// src/main.js\n\nconst info = new URL(import.meta.url).searchParams.get('info');\nconsole.log(info); // 5
\n

이런 식으로 모듈끼리의 정보도 주고받을 수 있다. 이는 Node.js 환경에서도 마찬가지이다.

\n
// some.js\n\nexport function callImportMeta() {\n  return new URL(import.meta.url).searchParams.get('id');\n}
\n
// main.js\n\nimport { callImportMeta } from './some.js?id=pozafly';\nconsole.log(callImportMeta()); // pozafly
\n

메타 정보를 쿼리 파라미터로 주고받았다.

\n

node.js와 browser 모두 meta 정보에 접근할 수 있다. 근데 Vite에서는 왜 dotenv를 쓰는 걸까? env를 단순히 읽어들이기 위해서일까?

\n

Vite로 프로젝트를 실행하고 Chrome devTools의 source 탭에 App.tsx가 트랜스파일링 된 파일을 보면

\n

\n \n \n

\n

HTML head 태그에 /@vite/client 를 불러오도록 명시하고 있다. 따라서 진입점은 client.ts 파일이다.

\n
// @vite/client.ts (간추린 버전)\n\nconst importMetaUrl = new URL(import.meta.url);\nconst socketProtocol = importMetaUrl.protocol === 'https:' ? 'wss' : 'ws';\nconst socketHost = `${importMetaUrl.hostname}:${importMetaUrl.port}`;\n\nlet socket = setupWebSocket(socketProtocol, socketHost);\n\nfunction setupWebSocket(protocol, hostAndPath) {\n  const socket = new WebSocket(`${protocol}://${hostAndPath}`, 'vite-hmr');\n  let isOpened = false;\n\n  // Listen for messages\n  socket.addEventListener('message', async ({ data }) => {\n    handleMessage(JSON.parse(data));\n  });\n\n  return socket;\n}
\n

importMetaUrl 은 import.meta.url을 URL 객체화 한 정보를 가지고 있다.

\n
importMetaUrl: URL\n  hash: \"\"\n  host: \"localhost:5173\"\n  hostname: \"localhost\"\n  href: \"http://localhost:5173/@vite/client\"\n  origin: \"http://localhost:5173\"\n  password: \"\"\n  pathname: \"/@vite/client\"\n  port: \"5173\"\n  protocol: \"http:\"\n  search: \"\"\n  searchParams: URLSearchParams\n    size: 0\n  username: \"\"
\n

위에서 살펴봤던 브라우저에 로드 된 @vite/client 모듈의 정보가 담겨있다. 쿼리 스트링에 담겨있을 searchParams 는 아직은 존재하지 않는다. 다시 소스를 보면, socket 연결을 위한 작업들을 하고 있다. 이 정보를 봤을 때, Vite의 devServer와 브라우저가 소켓 통신을 통해 어떤 정보를 주고받을 준비를 하는 것을 볼 수 있다.

\n

그리고 socket으로 message 이벤트를 감지하고 있는데, 브라우저의 소켓에서 메세지 이벤트를 devServer로부터 전달받으면 handleMessage 함수를 실행하도록 되어있다. 이를 기억하자.

\n

이제 HTML의 body 하단의 <script type=\"module\" src=\"/src/main.tsx\"></script> 코드가 실행되고, 어플리케이션이 실행된다. 렌더링이 종료되어 브라우저에 코드가 실행되고 난 후, 소스코드를 수정하면 재미있는 현상을 볼 수 있다.

\n

\n \n \n

\n

바로, 소스코드를 수정한 모듈에 쿼리 파라미터 t 가 새롭게 붙은 파일이 브라우저로 로드되어 새롭게 대체되는 현상이다.

\n
// @vite/client.ts (간추린 버전)\n\nasync function handleMessage(payload) {\n  switch (payload.type) {\n    // ...\n    case 'update':\n      if (isFirstUpdate) {\n        window.location.reload();\n        return;\n      }\n      await Promise.all(\n        payload.updates.map(async (update) => {\n          if (update.type === 'js-update') {\n            return hmrClient.fetchUpdate(update);\n          }\n          // CSS 관련 HMR 소스코드 더 있음.\n        })\n      );\n  }\n}
\n

socket을 브라우저에 등록하는 과정에서 message 이벤트가 일어나면 실행할 handleMessage 함수를 등록했다. 바로 그 함수가 실행되는데 JavaScript 함수이므로 hmrClient.fetchUpdate() 함수가 실행된다.

\n

hmrClient는 마찬가지로 Vite가 처음 브라우저로 넘어왔을 때 만들어진 인스턴스인데, 이는 아래와 같다.

\n
// @vite/client.ts (간추린 버전)\n\nconst hmrClient = new HMRClient(async function importUpdatedModule({\n  acceptedPath,\n  timestamp,\n  explicitImportRequired,\n}) {\n  const [acceptedPathWithoutQuery, query] = acceptedPath.split(`?`);\n  return await import(\n    base +\n      acceptedPathWithoutQuery.slice(1) +\n      `?${explicitImportRequired ? 'import&' : ''}t=${timestamp}${query ? `&${query}` : ''}`\n  );\n});
\n

이곳이 핵심이다. await import() 를 사용해 어떤 다른 모듈을 동적으로 불러오는 것을 볼 수 있다. t= 로 시작하는 쿼리 파라미터가 있으며, t에는 timestamp가 존재한다. dev-tools에서 봤던, App.tsx?t=xxx 는 이것이다.

\n

HMRClient class를 보자.

\n
// @vite/hmr.ts (간추린 버전)\n\nexport class HMRClient {\n  constructor(importUpdatedModule) {\n    this.importUpdatedModule = importUpdatedModule;\n  }\n\n  public async fetchUpdate(update) {\n    const { path, acceptedPath } = update;\n    const isSelfUpdate = path === acceptedPath;\n\n    if (isSelfUpdate) {\n      await this.importUpdatedModule(update);\n    }\n\n    return () => {\n      for (const { deps, fn } of qualifiedCallbacks) {\n        fn(deps.map((dep) => (dep === acceptedPath ? fetchedModule : undefined)));\n      }\n    };\n  }\n}
\n

importUpdatedModule 을 받는다. 이는 HMRClinet class를 생성할 때 받는 함수 자체를 말하는데, 결국 이게 실행되는 것은, await imort() 동적 모듈을 가져오는 과정이다.

\n

결국 @vite/client.ts 에 있던 socket의 addEventListener에 등록된 handleMessage 에서 넘겨받은 payload 안에 update 객체가 들어있고, update 객체에서는 이것이 js인지 css인지 구분하는 값과, timestamp 값, query 등의 값이 들어있다. 즉, 이 정보는 모두 devServer에서 만들어주어 socket으로 브라우저로 전송되어 입력되며 동적 import를 통해 다시 수정된 파일을 devServer에서 다시 브라우저로 전송하는 것이다.

\n

이를 도식화 해보면 아래와 같다.

\n

\n \n \n

\n

Vite는 import.meta를 통해 모듈의 정보를 이용해 HMR를 구현했다. url을 통해 모듈의 경로와 메타 데이터를 활용해 socket를 세팅하고, 소스코드 변경이 일어나면 모든 모듈을 교체하는 것이 아니라 변경된 코드가 담긴 모듈만 동적 import를 통해 교체하는 것이다.

\n

App.tsx에서 import.meta.hot 을 콘솔에 찍어보면

\n

\n \n \n

\n

이런 정보를 가지고 있고, 그중 hotModulesMap 도 들어있다.

\n

\n \n \n

\n

hotModulesMap은, 현재 소스코드를 Vite가 code splitting을 통해 모듈로 나눠놓은 것을 담고 있다. 이 모듈에서 socket으로부터 받은 payload의 정보를 통해 모듈을 교체하기 때문에 훨씬 효율적으로 모듈을 교체할 수 있는 것이다.

\n

참고로, .env 파일의 환경 변수를 담는 import.meta.env 와 HMR의 모듈 교체를 위한 map을 담고 있는 import.meta.hot 는 브라우저로 전송되는 .tsx 모든 모듈의 상단에서 주입하고 있다. 위에서 봤던 사진을 다시 한번 보자.

\n

\n \n \n

\n

Vite 빌드 결과

\n

\n \n \n

\n

14s → 5s로 약 62% build 속도가 증가되었다. Vite는 내부적으로 빌드 시 rollup을 사용하기 때문에 Webpack에 비해 더욱 빠른 속도로 빌드 할 수 있다. (devServer는 esbuild로 번들링)

\n
\n

마치며

\n

import.meta는 모듈의 메타 데이터를 저장하고, 활용할 수 있는 도구다. 이전에 import.meta가 없었을 때는 Node.js 환경에서 아래 코드와 같이 파일의 경로를 알아내고, 파일을 읽어올 수 있었다.

\n
// Node.js 환경\n\nconst fs = require('fs');\nconst path = require('path');\nconst bytes = fs.readFileSync(path.resolve(__dirname, 'data.bin'));
\n

또한, 브라우저 환경에서 모듈에 대한 메타 데이터를 얻을 수 있는 방법은 아래와 같았다.

\n
<!-- 브라우저 환경 -->\n\n<script data-option=\"value\" src=\"library.js\"></script>\n\n<script>\n  const theOption = document.currentScript.dataset.option;\n</script>
\n

하지만, Node.js 환경에서는 fs와 path 라이브러리를 항상 가지고 있어야 하며, 브라우저 환경에서는 현재 실행되고 있는 스크립트가 반드시 library.js 모듈일지는 불명확했기 때문에 문제가 되었다. 따라서 TC39에 import.meta에 대한 제안이 올라왔고 구현되었다.

\n

import.meta는 비교적 최신 문법이며, 따라서 구형 브라우저에서는 동작하지 않는다. Vite는 import.meta를 사용하기 때문에 자연스럽게 구형 브라우저에서는 사용할 수 없다. 하지만, @vitejs/plugin-legacy를 사용한다면 가능하다.

\n

또한, Vite의 discussions를 보면 process.env 대신 import.meta를 사용하는 이유에 대한 답변으로 ECMAScript 모듈의 ‘새로운’ 표준이기 때문에 사용한다라는 답변이 있다. 물론 import.meta는 ECMAScript의 새로운 표준이기도 하지만 Vite가 개발 모드에서 브라우저에 모듈을 서빙하는 과정을 보면 브라우저 자체가 모듈을 다룰 수 있도록 하고, 빠른 번들링 및 모듈 교체를 위함임을 알 수 있다. 이는 Vite의 철학과도 연관되어 있다.

\n

Vite로 마이그레이션 하면서 process.env대신, import.meta를 사용하는 이유가 궁금했다. 결과, import.meta MDN 문서도 함께 번역해 보면서 번들러가 어떻게 이를 사용하고 있는지 살펴볼 수 있는 시간이었다.

\n
\n

참고

\n\n
","htmlAst":{"type":"root","children":[{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/vuejs/vue-cli","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"vue-cli"}]},{"type":"text","value":"는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 패키지 내부에는 eslint, prettier가 vue-cli에 맞게 묶여있었는데 최신 버전의 eslint, prettier 버전을 사용하고 싶어도 호환이 되지 않았다. 그래서 vue-cli 대신 번들러를 바꿔 개발 환경을 최신화하기로 했다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"예전부터 사용해 보고 싶었던 번들러는 Vite다. Vite의 가장 큰 특징은 devServer에서 소스코드와 디펜던시를 두 가지 카테고리로 나누어 빌드하고, ESM 환경인, 브라우저에 빠르게 제공한다는 점이다. devServer가 cold-start 될 때 현재 페이지에서 필요한 정보만 아주 빠르게 실행시킬 수 있다. 이 말은, 코드 베이스 또는 라이브러리(사용하고 있는 node_modules 디펜던시)의 모든 파일을 번들링 하여 제공하는 것이 아니라, 현재 필요한 모듈만 골라내어 빠르게 제공한다는 뜻이다. Vite 가이드에서 가장 먼저 이야기하고 있는 것이 ESM을 통한 devServer start 속도이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"사전 번들링은, esBuild를 통해 디펜던시를 빌드하고, 변경이 잦은 소스코드는 ESM으로 제공한다. 기존에 Webpack과 같은 번들러는 모든 파일을 빌드 및 번들링 해야만 브라우저에서 구동이 가능했다. Vite는 소스코드를 ESM으로 제공하기 때문에 브라우저에서 동적 import를 통해 원하는 JavaScript 파일만 실행시킬 수 있다. 이 매커니즘에 따라 Webpack의 Node.js에서만 가능했던 기능이 브라우저에서 동작하기 위해 어떻게 Vite가 해결했는지를 알아볼 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"Nodejs-환경-변수","style":"position:relative;"},"children":[{"type":"text","value":"Node.js 환경 변수"},{"type":"element","tagName":"a","properties":{"href":"#Nodejs-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98","ariaLabel":"Nodejs 환경 변수 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"processenv","style":"position:relative;"},"children":[{"type":"text","value":"process.env"},{"type":"element","tagName":"a","properties":{"href":"#processenv","ariaLabel":"processenv permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"대부분의 bundler는 Node.js 환경 위에서 동작한다. Node.js에서는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"process"}]},{"type":"text","value":" 라는 특별한 이름의 예약어를 사용해 환경 변수에 접근할 수 있다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"process"}]},{"type":"text","value":" 예약어는 현재 실행되고 있는 Node.js 프로세스에 대한 정보를 가지고 있고 이를 제어할 수 있는 객체다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"대부분의 JavaScript 프레임워크에서는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"process.env"}]},{"type":"text","value":" 변수를 통해 환경 변수에 접근한다. process.env는 런타임에 동적으로 변수를 추가 및 수정할 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"text","value":"console"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"TEST"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// undefined"}]},{"type":"text","value":"\nprocess"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"TEST"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"test!\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"TEST"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// test!"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위 코드를 Node.js의 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" 명령어로 실행하면 주석과 같은 결과를 얻을 수 있다. 프레임워크에서는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 통해 process.env 변수에 개발자가 설정한 변수를 process.env에 주입시켜주는데, 주로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리를 통해 주입한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"dotenv","style":"position:relative;"},"children":[{"type":"text","value":"dotenv"},{"type":"element","tagName":"a","properties":{"href":"#dotenv","ariaLabel":"dotenv permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"모던 JavaScript 프레임워크에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라는 라이브러리를 내부적으로 래핑해서 사용하고 있다. "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/motdotla/dotenv","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리는 node.js 환경 및 ESM 환경에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일에 있는 환경 변수를 런타임 환경의 JavaScript로 들고 올 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"라이브러리를 가볍게 분석해 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"sh"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-sh"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-sh"]},"children":[{"type":"text","value":"$ "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" init "},{"type":"element","tagName":"span","properties":{"className":["token","parameter","variable"]},"children":[{"type":"text","value":"-y"}]},{"type":"text","value":"\n$ "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","parameter","variable"]},"children":[{"type":"text","value":"-D"}]},{"type":"text","value":" dotenv"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"명령어로 npm 환경을 생성한다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"package.json"}]},{"type":"text","value":" 파일이 생성된 후, dotenv 라이브러리를 다운로드 받았다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"프로젝트 root에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 생성하고 테스트 값을 넣는다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"# .env file\nTEST=ENV_TEST!"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"main.js 파일을 생성하고, dotenv 라이브러리를 통해 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일의 환경 변수 값을 가져와보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// src/main.js"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"dotenv\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"config"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"TEST"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ENV_TEST!"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이제 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" 명령어로 Node.js 환경에서 이를 실행시켜보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"sh"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-sh"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-sh"]},"children":[{"type":"text","value":"$ "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" src/main.js\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":">"}]},{"type":"text","value":" ENV_TEST"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"어떻게 이런 결과가 나올까? dotenv 라이브러리를 살짝 까보자. 시작은 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"require(\"dotenv\").config();"}]},{"type":"text","value":" 줄이다. config 메서드를 실행한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"config"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"options"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"_dotenvKey"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"options"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"length "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"0"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" DotenvModule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"configDotenv"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"options"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"configDotenv()"}]},{"type":"text","value":" 함수를 실행한다. "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/motdotla/dotenv/blob/8076cbb4ae64b531308b42b5f27d35f49b74ed83/lib/main.js#L205","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"lib/main.js의 configDotenv 함수"}]},{"type":"text","value":". "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일의 경로를 읽고 파싱 해 process 환경을 파싱 된 값으로 채우고 반환한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"configDotenv"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"options"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" dotenvPath "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"cwd"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'.env'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" parsed "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" DotenvModule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"parse"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"fs"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"readFileSync"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"dotenvPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" encoding "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" processEnv "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"options "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"&&"}]},{"type":"text","value":" options"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"processEnv "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"!="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"null"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n processEnv "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" options"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"processEnv"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n DotenvModule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"populate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"processEnv"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" parsed"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" options"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" parsed "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"dotenvPath 변수에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일의 경로를 저장한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"process.cwd()"}]},{"type":"text","value":" : node 명령을 호출한 디렉토리의 절대 경로다. /Users/pozafly/Documents/dev/play-ground/dotenv-exam"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"path.resolve()"}]},{"type":"text","value":" : 경로를 묶어 새로운 경로를 반환한다. /Users/pozafly/Documents/dev/play-ground/dotenv-exam/.env"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"parsed 변수에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 파싱 해 담는다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"fs.readFileSync()"}]},{"type":"text","value":" : 인자로 들어오는 절대 경로로 파일 text 값을 읽어온다. 따라서, dotenvPath의 값을 읽어온다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"DotenvModule.parse()"}]},{"type":"text","value":" : 파싱 한 text 값을 JavaScript object로 만들어서 return 한다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"parsed: { TEST: 'ENV_TEST!' }"}]},{"type":"text","value":" 값이 담겨있다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"populate(processEnv, parsed, options)"}]},{"type":"text","value":" 실행한다. populate는 ‘덧붙이다’라는 뜻을 가지고 있다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"populate"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"processEnv"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" parsed"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" options "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Set process.env"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" key "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" Object"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"keys"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"parsed"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n processEnv"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" parsed"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"processEnv = process.env"}]},{"type":"text","value":" 로 레퍼런스 주소를 묶어주었기 때문에 key로 즉시 할당한다. 다시 우리가 작성했던 main.js 구문을 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'dotenv'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"config"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"TEST"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ENV_TEST!"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"정리하면, dotenv 라이브러리는 Node.js 환경에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 를 파싱 해 text 값을 통해 객체를 생성하고, process.env에 값을 추가해 Node.js 환경의 전역에 노출된다. JavaScript 프레임워크에서는 보통 Node.js를 한 번만 실행하기 때문에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일의 환경 변수 값이 변경되면 devServer를 껐다 켜주어야 값을 변경된 값으로 반영할 수 있는 이유이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite는 바로 반영이 되는데, devServer를 순간적으로 다시 시작시켜준다. .env 파일에서 변수를 변경하면 터미널 log에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"server restarted."}]},{"type":"text","value":"라고 알려준다. Vite는 Webpack처럼 모든 파일을 번들링 하지 않기 때문에 무척 빠르기에 가능하다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"dotenv에서 ESM 환경 또한 지원한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// package.json"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","string-property","property"]},"children":[{"type":"text","value":"\"type\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"module\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위와 같이 package.json 파일에 type을 module로 넣어주면 Node.js에서 ESM 코드를 사용할 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"※ Vite로 마이그레이션을 진행할 때도, package.json에 위와 같이 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"type\": \"module\""}]},{"type":"text","value":" 을 넣어주어야 하는데, Vite는 기본적으로 ESM 방식으로 동작한다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"참고고, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"main.js"}]},{"type":"text","value":" 파일을, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"main.mjs"}]},{"type":"text","value":" 라는 확장자를 붙여주면 Node.js에서 알아서 ESM으로 동작하게 되기 때문에 package.json에 따로 붙여줄 필요는 없다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"vue-cli는 @vue/cli-services 패키지 내에서 사용하고 있고, CRA 같은 경우 react-scripts 라이브러리 내부 package.json에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 을 사용하고 있으며 Next.js도 내부적으로 dotenv 라이브러리를 이용해 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 가져오고 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"※ "},{"type":"element","tagName":"a","properties":{"href":"https://nodejs.org/dist/latest-v20.x/docs/api/cli.html#--env-fileconfig","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"—env-file"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"node.js 20 버전부터는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"--env-file=config"}]},{"type":"text","value":" 를 통해 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리 없이 사용할 수 있도록 개발 중이다. 실제로 터미널에서 node 명령어로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일을 지정 해 줄 수 있다. 아직은 실험용."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"sh"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-sh"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-sh"]},"children":[{"type":"text","value":"$ "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"node"}]},{"type":"text","value":" --env-file"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":".env --env-file"},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":".development.env index.js"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"// .env\nPORT=3000"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"따라서, 이제는 점차 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리가 필요없어지게 될 것 같다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"모드-별-환경-변수-접근","style":"position:relative;"},"children":[{"type":"text","value":"모드 별 환경 변수 접근"},{"type":"element","tagName":"a","properties":{"href":"#%EB%AA%A8%EB%93%9C-%EB%B3%84-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%A0%91%EA%B7%BC","ariaLabel":"모드 별 환경 변수 접근 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"하지만, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일만 있는 것이 아니라 배포 환경에 따라 환경 변수의 값이 달라져야 환경 변수를 사용하는 의미가 있다. 즉, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env.development"}]},{"type":"text","value":", "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env.production"}]},{"type":"text","value":" 등의 환경 변수 파일이 추가로 필요하고 mode에 따라 지정된 값이 process.env 값에 할당되어 build 되어야 한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://github.com/mrsteele/dotenv-webpack","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"dotenv-webpack"}]},{"type":"text","value":" 플러그인은 아주 간단하게 직접 path를 지정하도록 되어 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"먼저 사용법을 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// webpack.config.js"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" Dotenv "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'dotenv-webpack'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\nmodule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"exports "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"plugins"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Dotenv"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"path"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'.env.production'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"webpack 설정 파일에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"new Dotenv()"}]},{"type":"text","value":" 를 통해 인스턴스를 만든다. 인자로 path key를 가진 객체를 넣어주는데, 빌드 시 적용할 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env.production"}]},{"type":"text","value":" 파일의 경로를 적어준다. 그럼, dotenv-webpack 플러그인을 보자. "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/mrsteele/dotenv-webpack/blob/97a864d72302d25fad0cef618fcd3f09e94bc4e4/src/index.js#L22","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"dotenv-webpack 소스"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" dotenv "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'dotenv-defaults'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"class"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Dotenv"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 1."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"constructor"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"config "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Object"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"assign"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"path"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./.env'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"prefix"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'process.env.'"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n \n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 3."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"getEnvs"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"config"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" env "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" dotenv"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"parse"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"loadFile"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","literal-property","property"]},"children":[{"type":"text","value":"file"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n env\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n \n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"gatherVariables"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" env "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"getEnvs"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 2."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" vars "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" Object"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"assign"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" process"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 4."}]},{"type":"text","value":"\n\n Object"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"keys"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"forEach"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"key"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" value "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"Object"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"prototype"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"hasOwnProperty"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"call"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"vars"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" vars"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" env"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n vars"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"key"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 5."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" vars"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"간추린 코드만 들고 왔다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ol","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"인스턴스를 생성할 때, 넣어준 path를 생성자에서 설정한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"getEnvs()"}]},{"type":"text","value":" 메서드 실행."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"text","value":"config에 담긴 path를 가져와 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env*"}]},{"type":"text","value":" 파일을 가져오고, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리에 parse 메서드를 사용해 env 객체로 만들어 return."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"vars"}]},{"type":"text","value":" 에 새로운 객체에다가 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"process.env"}]},{"type":"text","value":" 값을 복사한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"vars[key] = value"}]},{"type":"text","value":" 를 통해 파싱 한 값을 집어넣어 return."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"즉, dotenv-webpack은 단순히 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 값을 path로 받아 파싱 한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"Vite의-환경-변수-접근","style":"position:relative;"},"children":[{"type":"text","value":"Vite의 환경 변수 접근"},{"type":"element","tagName":"a","properties":{"href":"#Vite%EC%9D%98-%ED%99%98%EA%B2%BD-%EB%B3%80%EC%88%98-%EC%A0%91%EA%B7%BC","ariaLabel":"Vite의 환경 변수 접근 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite는 환경 변수가 정의된 파일("},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":")에서 여타 번들러와 마찬가지로 어플리케이션에 필요한 변수를 가져와 사용할 수 있다. Vite의 경우 "},{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/env-and-mode.html","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"공식 문서에서 환경 변수 접근법"}]},{"type":"text","value":"에 대해 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta"}]},{"type":"text","value":"라는 JavaScript 문법으로 접근할 것을 알려주고 있다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".env"}]},{"type":"text","value":" 파일에 환경과 관련된 변수를 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"VITE_"}]},{"type":"text","value":" prefix를 주고, 코드 상에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.env"}]},{"type":"text","value":" 로 선언한 값을 들고 올 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"h3","properties":{"id":"importmeta","style":"position:relative;"},"children":[{"type":"text","value":"import.meta"},{"type":"element","tagName":"a","properties":{"href":"#importmeta","ariaLabel":"importmeta permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/import.meta","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"import.meta"}]},{"type":"text","value":"라는 JavaScript 문법을 알아보며 MDN 문서에 아직 아무도 번역하지 않아 이번 기회에 함께 번역해 보았다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta"}]},{"type":"text","value":" 는 ES Module이 탄생하면서 모듈에 대한 메타 데이터(부수 데이터)를 저장하기 위한 객체다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"여기서 말하는 메타 데이터란, 이미지 파일을 생각하면 조금 더 이해하기 쉽다. 휴대폰으로 사진을 찍으면 사진의 메타 데이터에 ‘날짜’, ‘사진 용량’, ‘디바이스 정보’, ‘위치 데이터’ 등의 메타 데이터가 담기게 된다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta"}]},{"type":"text","value":" 는 ‘모듈’ 자체에 대한 메타 데이터를 담고 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"import.meta는 대표적으로 모듈 메타 데이터인 경로(URL)를 담고 있는데, 이는 호스트 환경(브라우저 혹은 Node.js)에 따라 저장되는 내용이 달라진다. 먼저 Node.js를 통해 import.meta가 가지고 있는 정보를 열어보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// src/main.js"}]},{"type":"text","value":"\n\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"meta"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"node 명령어로 main.js를 실행시키면 SyntaxError가 발생한다. 이유는, node.js는 기본적으로 CommonJS 환경에서 동작하기 때문이다. import.meta는 ESM 환경에서 동작하기 때문에 이런 에러가 발생하는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Node.js에서 import.meta를 사용하는 방법은 2가지인데, 하나는 main.js 파일을 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"main.mjs"}]},{"type":"text","value":" 로 ESM에서 동작하는 JavaScript 확장자를 붙여주어 node 명령어로 다시 실행시키는 방법이고, 다른 하나는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"dotenv"}]},{"type":"text","value":" 라이브러리에서 ESM 환경으로 동작시킬 때 알아본 package.json 파일에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"\"type\": \"module\""}]},{"type":"text","value":" 을 명시해 주는 방법이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// src/main.js"}]},{"type":"text","value":"\n\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"meta"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"/**\n * [Object: null prototype] {\n * dirname: '/Users/pozafly/Documents/dev/play-ground/esm-exam/src',\n * filename: '/Users/pozafly/Documents/dev/play-ground/esm-exam/src/main.js',\n * resolve: [Function: resolve],\n * url: 'file:///Users/pozafly/Documents/dev/play-ground/esm-exam/src/main.js'\n * }\n*/"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위와 같은 결과를 얻었다. dirname, filename, resolve, url 등의 정보가 들어있다. 절대 경로로 내 파일(모듈)의 위치를 가리키고 있다. 그렇다면 브라우저에서는 어떻게 동작하는가?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"간단하게 "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/johnpapa/lite-server","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"lite-server"}]},{"type":"text","value":"를 설치하고 index.html 파일을 브라우저로 서빙해보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"sh"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-sh"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-sh"]},"children":[{"type":"text","value":"$ "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"npm"}]},{"type":"text","value":" i "},{"type":"element","tagName":"span","properties":{"className":["token","parameter","variable"]},"children":[{"type":"text","value":"-D"}]},{"type":"text","value":" lite-server"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"json"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-json"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// package.json"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"type\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"module\""}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"scripts\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"dev\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"lite-server\""}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"devDependencies\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","property"]},"children":[{"type":"text","value":"\"lite-server\""}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"\"^2.6.1\""}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"dev 스크립트를 입력해 주고, index.html 파일을 만들어 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"npm run dev"}]},{"type":"text","value":" 명령어를 실행한다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"html"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":""}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","doctype"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"html"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"head"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"type"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"module"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"src"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"./src/main.js"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"body"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 804px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 15%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAnklEQVR42m2Oyw6CMBBF+f/Pc+fCBy6q0EKhD6xM67Fg3HmTm5NJJjenCSEwmIEUn4jWrMbsTbon3RV5sqzXC7ne2Y47yzwhy0Ksdc6xbYyjZY5CI1nQraI/nJmOLa7TGKVQpxP9rWX1bh8qbqbEQJ4rl0h5JSRnRIT8Y3nTUJOsJ3SW4n21rCabQd8hg6Fshrcr8rh/zXbT+hs8//IB617mnumNSiMAAAAASUVORK5CYII='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"browser-import.meta","title":"","src":"/static/7fa03cf5335260b60df14598ca0e8692/0c082/browser-import.meta.png","srcSet":["/static/7fa03cf5335260b60df14598ca0e8692/0eb09/browser-import.meta.png 500w","/static/7fa03cf5335260b60df14598ca0e8692/0c082/browser-import.meta.png 804w"],"sizes":"(max-width: 804px) 100vw, 804px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"resolve와, url 정보가 들어있다. Node.js 환경과는 조금 다르다. dirname, filename이 없다. 그리고 Node.js 환경에서의 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"url"}]},{"type":"text","value":" 은 모듈(파일)의 절대 경로가 들어가 있고, 브라우저 환경에서의 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"url"}]},{"type":"text","value":" 은 http server가 서빙하고 있는 주소 자체를 담고 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"여기서 재미있는 것을 하나 더 해볼 수 있는데, 바로 쿼리 파라미터로 원하는 값을 넣어줄 수 있다는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"html"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"type"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"module"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"src"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"./src/main.js?info=5"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이렇게, 쿼리 파라미터 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"info"}]},{"type":"text","value":"라는 key에 value를 5를 넣었다. 다시 실행해 보면, main.js가 모듈로서 여전히 호출되고"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 928px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 12.8%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAqUlEQVR42kWO227DMAxD8/+/N/SxawakTetrEruJ49g+U7sBfaBEQgLJbl03yrJwjDey8+THnaweHMaQrwO5v1DnmeM+UqyheEcx+q2PbSPEyCz3EALGOjp16jFfZ8Iw4rXj9n1+I4hhk+fiLG19UmOgPSMtJepLh4Wad2otlPJB5wdDmiO7UmQ/kbQmvbi03ZXwn54sydladi2tp+mfS8tFQoAmo7a//QuwYOXunQBTJwAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"import.meta.info","title":"","src":"/static/ff550c2f2284ef9887f1930c25196a93/cda85/import.meta.info.png","srcSet":["/static/ff550c2f2284ef9887f1930c25196a93/0eb09/import.meta.info.png 500w","/static/ff550c2f2284ef9887f1930c25196a93/cda85/import.meta.info.png 928w"],"sizes":"(max-width: 928px) 100vw, 928px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이렇게 url의 모습이 변경된 것을 볼 수 있다. 그러면 이 url 변수를 가공해 info 값을 얻을 수가 있는데,"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// src/main.js"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" info "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"URL"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"meta"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"searchParams"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'info'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"info"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// 5"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 식으로 모듈끼리의 정보도 주고받을 수 있다. 이는 Node.js 환경에서도 마찬가지이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// some.js"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"callImportMeta"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"URL"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"meta"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"searchParams"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"get"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'id'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// main.js"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" callImportMeta "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"from"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'./some.js?id=pozafly'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\nconsole"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"log"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"callImportMeta"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// pozafly"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"메타 정보를 쿼리 파라미터로 주고받았다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"node.js와 browser 모두 meta 정보에 접근할 수 있다. 근데 Vite에서는 왜 dotenv를 쓰는 걸까? env를 단순히 읽어들이기 위해서일까?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite로 프로젝트를 실행하고 Chrome devTools의 source 탭에 App.tsx가 트랜스파일링 된 파일을 보면"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1170px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 33.599999999999994%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABSUlEQVR42pWR0XKjMAxF+f+P6g/sbLJMkpIEkqbBBbKACSUp2MacikwfOn3ZWc3ckWRdXcty8PRLESU5iz8btvGZaHdiGUZsoiP7g+L38pnk+Ea42j3Ok6Nitd5L/cDL+cIi3BKu4wd3tUkI1nHB8tATHRsqfRd8cCk7LlWHllhfB+rWUDU9RSU1PVDo/sHTsy/fKQWV8Of+oHcTXXWnXWWkrzJtHJOmKSrPuaicIi+JT2+c0oLkVJCrkuw1o5Xaragw1wbTtgxNgx0GgnGC0ThsVlNsd+Txnrau6XWNsxbrHMYYnLN478CPTBJPo5Pc89MCJ4qiiX1vuYZLbirlI1Pc0zO26/inTXP39OW/C7az4EKeWnNWf2VsJ1OM/K8Fo0xtjMV0N6zW1Ne7fEKPcZ5BYL8wmJHBekaBF76XdXhZx+znix+5NXwCIv4VyibLESYAAAAASUVORK5CYII='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"source-tab","title":"","src":"/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png","srcSet":["/static/79da4e50c599e0226c48d5439368c947/0eb09/source-tab.png 500w","/static/79da4e50c599e0226c48d5439368c947/1263b/source-tab.png 1000w","/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png 1170w"],"sizes":"(max-width: 1170px) 100vw, 1170px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이렇게 되어 있다. env 파일에 정의한 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"VITE_xxx"}]},{"type":"text","value":" 변수 및 다른 변수가 브라우저 외부로 노출되어 있다. Vite는 우선 devServer(Node.js 환경)에서 환경 변수를 설정할 뿐 아니라, 위의 쿼리 파라미터를 이용해 다른 기능에도 응용하고 있다. 이 쿼리 파라미터를 어떻게 사용하고 있을까?"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"HMR","style":"position:relative;"},"children":[{"type":"text","value":"HMR"},{"type":"element","tagName":"a","properties":{"href":"#HMR","ariaLabel":"HMR permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"HMR(Hot Module Replacement)는 번들러 환경에서 개발할 때 주로 사용하는데, 소스코드를 변경하면 devServer를 새로 껐다 키지 않고 브라우저를 새로고침 하지 않아도 모듈을 교체해 변경된 부분을 즉시 볼 수 있게 만들어주는 기능이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite에서는 HMR 기능에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta"}]},{"type":"text","value":" 를 사용하고 있다. 브라우저에 로드 된 Sources 탭의 소스 맵에 breakpoint를 찍어 보면서 따라가보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"※ Vite는 컴퓨터에서 파일(소스코드) 변경 감지는 "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/paulmillr/chokidar","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"chokidar"}]},{"type":"text","value":"이라는 라이브러리를 사용하고 있다."}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1128px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 23%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAABHklEQVR42nWP6W6CUBCFef+Han81xi6pVmQpoqKgVbj3soNY+Do+QCc5OZPJ5CzWs9MydnemsiWvbpiyxwgPtzvUPYXRtOeMJlWk1zN1WTCOI/+NlaQVF3n8cCJev2Pmfszbg72A2cpnZgfMV998eDtmjs8ijFntE97DhFPmw/DJ2C+Z+oVgiVVVOW2aslt6vLtbXhYBy+BAEO1Z+zbexifYb1CFJDSpNDDSwKBzRVv9wO9FhM5M94sInx4JS6b6ht4kfDoHvtyIq9Q7HhO2YUgSx1wvVzIxzfMcrRRlWdEZQ5cpmqanzjR903GrGqyndU1fdMROyOaQso012yjGc11s28YVjiSt1ophGETUoLKMTFCUpdw1Skwq2adp4g9moHUBgT9WqgAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"dev-tools-break-point","title":"","src":"/static/5e3f5ccf6510d2cb1df2b892c55ece42/bac97/dev-tools-break-point.png","srcSet":["/static/5e3f5ccf6510d2cb1df2b892c55ece42/0eb09/dev-tools-break-point.png 500w","/static/5e3f5ccf6510d2cb1df2b892c55ece42/1263b/dev-tools-break-point.png 1000w","/static/5e3f5ccf6510d2cb1df2b892c55ece42/bac97/dev-tools-break-point.png 1128w"],"sizes":"(max-width: 1128px) 100vw, 1128px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"HTML head 태그에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"/@vite/client"}]},{"type":"text","value":" 를 불러오도록 명시하고 있다. 따라서 진입점은 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"client.ts"}]},{"type":"text","value":" 파일이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/client.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" importMetaUrl "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"URL"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"meta"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"url"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" socketProtocol "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" importMetaUrl"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"protocol "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'https:'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'wss'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'ws'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" socketHost "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"importMetaUrl"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"hostname"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":":"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"importMetaUrl"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"port"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" socket "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setupWebSocket"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"socketProtocol"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" socketHost"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"setupWebSocket"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"protocol"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" hostAndPath"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" socket "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"WebSocket"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"protocol"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"://"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"hostAndPath"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'vite-hmr'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"let"}]},{"type":"text","value":" isOpened "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","boolean"]},"children":[{"type":"text","value":"false"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Listen for messages"}]},{"type":"text","value":"\n socket"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"addEventListener"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'message'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" data "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","constant"]},"children":[{"type":"text","value":"JSON"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"parse"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"data"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" socket"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"importMetaUrl"}]},{"type":"text","value":" 은 import.meta.url을 URL 객체화 한 정보를 가지고 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"text"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-text"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"importMetaUrl: URL\n hash: \"\"\n host: \"localhost:5173\"\n hostname: \"localhost\"\n href: \"http://localhost:5173/@vite/client\"\n origin: \"http://localhost:5173\"\n password: \"\"\n pathname: \"/@vite/client\"\n port: \"5173\"\n protocol: \"http:\"\n search: \"\"\n searchParams: URLSearchParams\n size: 0\n username: \"\""}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"위에서 살펴봤던 브라우저에 로드 된 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@vite/client"}]},{"type":"text","value":" 모듈의 정보가 담겨있다. 쿼리 스트링에 담겨있을 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"searchParams"}]},{"type":"text","value":" 는 아직은 존재하지 않는다. 다시 소스를 보면, socket 연결을 위한 작업들을 하고 있다. 이 정보를 봤을 때, Vite의 devServer와 브라우저가 소켓 통신을 통해 어떤 정보를 주고받을 준비를 하는 것을 볼 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"그리고 socket으로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"message"}]},{"type":"text","value":" 이벤트를 감지하고 있는데, 브라우저의 소켓에서 메세지 이벤트를 devServer로부터 전달받으면 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"text","value":" 함수를 실행하도록 되어있다. 이를 기억하자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이제 HTML의 body 하단의 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":""}]},{"type":"text","value":" 코드가 실행되고, 어플리케이션이 실행된다. 렌더링이 종료되어 브라우저에 코드가 실행되고 난 후, 소스코드를 수정하면 재미있는 현상을 볼 수 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 432px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 87.03703703703702%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAARCAYAAADdRIy+AAAACXBIWXMAABYlAAAWJQFJUiTwAAACOklEQVR42p2UaXLaQBCFuf818jM3sCshrthgY0CbDTIIIcACCbGDNrR8GZYK8RrbU9WaHvXozZt+3SokcYBsLJD6MF0EDIc2URyT5zlfGYXA3/DQn2FMwHZm6E2NKIr3wa+AFnaPKFgjPbj8aoEzC7nTVFrt9h7wLXsXMEu3eyBlAN7cx2i3xNVHLz5M0/RjDEN/hdJyuDBgOA3oWV0ajQaqqqIoCpIk/fVrtdo+9lZKCodAxmoVYHZcIYyP6zp4nodt20wmE7F297ZYLATzIePx+B2Gx1Myf0neLuN7Q64rt8iyjKZpDAaDTwkkGB4BhTCRfkMSbHCnM8aC2Xy1wg/DA+AzezGOB54YLqekzRvWfYOrnz+o/r5AKl3S1UW+ElGXoQ9xdLDtcY7Cgx8GYt6eckiakLUU4vNvbB9kJvcKS1GPvtFk3lBZ6ncEHZ2xUsVT6zjSrZhrzMQ+T6szb6ps2/e7MjgCbtZkukTSLLFxbcqlErXKDZos0bzTuBcK270eUvWWiohVyiWK52fIYn1ZLCIL9RdSRbAOT1fObZOk+J2oWWdYu8a6KjIXpzvVMhtdE21kkT12yfd28nfvc5EmJs4zUcI1SVfGn3noHZOqULkvykZtNOk/Ph727LrkFYHyV8smWLEVV44WU2zRJSMBZgsg13FOKv7PnjLckFoa8WpOx+xiGAY9kTfLsj75c/insOP6GcFsjGn194C7ot4BfqSHn7RekmbMxyOykUG8WWL1+pim+SXAPwOFExUaKwTeAAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"t-query-params","title":"","src":"/static/f3469240e5ba64dfdecd6a6fb1abfbe5/dc3b1/t-query-params.png","srcSet":["/static/f3469240e5ba64dfdecd6a6fb1abfbe5/dc3b1/t-query-params.png 432w"],"sizes":"(max-width: 432px) 100vw, 432px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"바로, 소스코드를 수정한 모듈에 쿼리 파라미터 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"t"}]},{"type":"text","value":" 가 새롭게 붙은 파일이 브라우저로 로드되어 새롭게 대체되는 현상이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/client.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"payload"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"switch"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"payload"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"type"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// ..."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"case"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'update'"}]},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isFirstUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n window"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"location"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"reload"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" Promise"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"all"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n payload"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"updates"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"type "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'js-update'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" hmrClient"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// CSS 관련 HMR 소스코드 더 있음."}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"socket을 브라우저에 등록하는 과정에서 message 이벤트가 일어나면 실행할 handleMessage 함수를 등록했다. 바로 그 함수가 실행되는데 JavaScript 함수이므로 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"hmrClient.fetchUpdate()"}]},{"type":"text","value":" 함수가 실행된다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"hmrClient는 마찬가지로 Vite가 처음 브라우저로 넘어왔을 때 만들어진 인스턴스인데, 이는 아래와 같다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/client.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" hmrClient "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"new"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"HMRClient"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"function"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n timestamp"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n explicitImportRequired"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"["}]},{"type":"text","value":"acceptedPathWithoutQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" query"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"]"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"split"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"?"}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"import"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"\n base "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":"\n acceptedPathWithoutQuery"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"slice"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","number"]},"children":[{"type":"text","value":"1"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"+"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"?"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"explicitImportRequired "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'import&'"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"t="}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"timestamp"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"query "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","template-string"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"&"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"${"}]},{"type":"text","value":"query"},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"''"}]},{"type":"element","tagName":"span","properties":{"className":["token","interpolation-punctuation","punctuation"]},"children":[{"type":"text","value":"}"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","template-punctuation","string"]},"children":[{"type":"text","value":"`"}]}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이곳이 핵심이다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await import()"}]},{"type":"text","value":" 를 사용해 어떤 다른 모듈을 동적으로 불러오는 것을 볼 수 있다. "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"t="}]},{"type":"text","value":" 로 시작하는 쿼리 파라미터가 있으며, t에는 timestamp가 존재한다. dev-tools에서 봤던, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"App.tsx?t=xxx"}]},{"type":"text","value":" 는 이것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"HMRClient class를 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/hmr.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"export"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"class"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","class-name"]},"children":[{"type":"text","value":"HMRClient"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"constructor"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"importUpdatedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" importUpdatedModule"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"public"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" isSelfUpdate "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isSelfUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fn "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" qualifiedCallbacks"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"dep"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"dep "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" fetchedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"undefined"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"text","value":" 을 받는다. 이는 HMRClinet class를 생성할 때 받는 함수 자체를 말하는데, 결국 이게 실행되는 것은, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await imort()"}]},{"type":"text","value":" 동적 모듈을 가져오는 과정이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"결국 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"@vite/client.ts"}]},{"type":"text","value":" 에 있던 socket의 addEventListener에 등록된 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"handleMessage"}]},{"type":"text","value":" 에서 넘겨받은 payload 안에 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"update"}]},{"type":"text","value":" 객체가 들어있고, update 객체에서는 이것이 js인지 css인지 구분하는 값과, timestamp 값, query 등의 값이 들어있다. 즉, 이 정보는 모두 devServer에서 만들어주어 socket으로 브라우저로 전송되어 입력되며 동적 import를 통해 다시 수정된 파일을 devServer에서 다시 브라우저로 전송하는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이를 도식화 해보면 아래와 같다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1920px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 56.199999999999996%; position: relative; bottom: 0; left: 0; background-image: url('data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAMCBAYJ/8QAFAEBAAAAAAAAAAAAAAAAAAAAAv/aAAwDAQACEAMQAAAB7fN2tNGQsK//xAAZEAADAQEBAAAAAAAAAAAAAAABAgMEBRP/2gAIAQEAAQUCniS+ms8/Wy5zYzIBJmqpCaef/8QAHREAAQQDAQEAAAAAAAAAAAAAAQIDBBMREiIUEP/aAAgBAwEBPwGMkQ3b4gEV70CXdHFDvqGmJNjeqrxWjD2bOE9cj5//xAAdEQEAAgEFAQAAAAAAAAAAAAACAQMiBBARISMT/9oACAECAQE/Abm9QYF7V4NXwItU2E0ZeJL5iKsl5xhkuu52/8QAKRAAAgECAwcEAwAAAAAAAAAAAQIDBBIAESEFFCIxMkFREyMkM1Jhgf/aAAgBAQAGPwKm2vV0G7bVjiki9useqWJA0sajhkgppL4nuuMBZTJZzQNieiqZN5hdkZ0tkpswkySxLfDKsotkReJWF3I6G0/I9ISZn6SSmXbq1zy5418Ye0fk3Ux1Ovc+f5gcCDMsTkqjv+hj/8QAHRABAQACAgMBAAAAAAAAAAAAAREAITFBUWFxkf/aAAgBAQABPyGa8ACbNMprDWa8httA6GbSIRWwrhLpt3un8G8AYIjhTadnhMDkDt2KnZztPiTLY5gEbKgFgF9Gf//aAAwDAQACAAMAAAAQjM//xAAWEQEBAQAAAAAAAAAAAAAAAAABEQD/2gAIAQMBAT8QTL6BIqYXZUkqBjv/xAAYEQEAAwEAAAAAAAAAAAAAAAABABEhYf/aAAgBAgEBPxCg9fXMMH5gDpp//8QAGhABAQADAQEAAAAAAAAAAAAAAREAITFBUf/aAAgBAQABPxAV8uSCEoM9mID9AyJpyHRyag+cYCbnd4ApFWALONMQWvo4duPw1ACfz8Pi4GmFUUxu9wr5FQFgZ//Z'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"hmr-process","title":"","src":"/static/7cf438b0f3030e920cede70837548650/aaf92/hmr-process.jpg","srcSet":["/static/7cf438b0f3030e920cede70837548650/953fe/hmr-process.jpg 500w","/static/7cf438b0f3030e920cede70837548650/0a251/hmr-process.jpg 1000w","/static/7cf438b0f3030e920cede70837548650/aaf92/hmr-process.jpg 1920w"],"sizes":"(max-width: 1920px) 100vw, 1920px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite는 import.meta를 통해 모듈의 정보를 이용해 HMR를 구현했다. url을 통해 모듈의 경로와 메타 데이터를 활용해 socket를 세팅하고, 소스코드 변경이 일어나면 모든 모듈을 교체하는 것이 아니라 변경된 코드가 담긴 모듈만 동적 import를 통해 교체하는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"App.tsx에서 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 을 콘솔에 찍어보면"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1758px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 11.799999999999999%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaklEQVR42l2MzQrDIBgE8/4vV3rP2WLNJxr/qTq1lxB6GHZgl91EvVHPHaM0VizeGKzWhBAJMSIiOOdJKeH9udyRc+Y4BH9GWmuUXKi10ntnS+J5PXbcOixrnEKgfTpzzosxxpV3/+9/fAFV7ZqPzoibTgAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"import.meta.hot","title":"","src":"/static/a917e557116f09da5960c8a9995cadc2/cbcea/import.meta.hot.png","srcSet":["/static/a917e557116f09da5960c8a9995cadc2/0eb09/import.meta.hot.png 500w","/static/a917e557116f09da5960c8a9995cadc2/1263b/import.meta.hot.png 1000w","/static/a917e557116f09da5960c8a9995cadc2/cbcea/import.meta.hot.png 1758w"],"sizes":"(max-width: 1758px) 100vw, 1758px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이런 정보를 가지고 있고, 그중 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"hotModulesMap"}]},{"type":"text","value":" 도 들어있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 806px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 28.599999999999998%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAGCAYAAADDl76dAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA+UlEQVR42pVR12rEMBD0//9Z3nLE4CrccJFLXOUqe+LdcBfyFCIYVit2htmRUQcZsjcb8l1APgSqjwClLBHFMfq+x3+PoSaFKivQlBWqW6itP7HMC+Z5xr7vOI6DQf22bdBaM/G6rl9Cz97Q14lCxLdQgzTLkKYpXNeF53lIkgR5nnO1bZvfuq57iY/jyP00TT8O9alRJwX6toOUEkVRIAgCmKYJIQSiKILjOK/q+z7jOUcIw5C5bdt+OyyDlFfN7yFyY1kWD5HbpmlYgMTJ7bquUEoxyCWtSnUYBnZu0MPS9BjaEYPacN4ZEYlyo7zO8+QsiUT3vz7lC76EyZDe5Ux1AAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"hotModulesMap","title":"","src":"/static/23b60f30ed3e8c840519669b599d7294/30577/hotModulesMap.png","srcSet":["/static/23b60f30ed3e8c840519669b599d7294/0eb09/hotModulesMap.png 500w","/static/23b60f30ed3e8c840519669b599d7294/30577/hotModulesMap.png 806w"],"sizes":"(max-width: 806px) 100vw, 806px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"hotModulesMap은, 현재 소스코드를 Vite가 code splitting을 통해 모듈로 나눠놓은 것을 담고 있다. 이 모듈에서 socket으로부터 받은 payload의 정보를 통해 모듈을 교체하기 때문에 훨씬 효율적으로 모듈을 교체할 수 있는 것이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"참고로, .env 파일의 환경 변수를 담는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.env"}]},{"type":"text","value":" 와 HMR의 모듈 교체를 위한 map을 담고 있는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 는 브라우저로 전송되는 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":".tsx"}]},{"type":"text","value":" 모든 모듈의 상단에서 주입하고 있다. 위에서 봤던 사진을 다시 한번 보자."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1170px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 33.599999999999994%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAYAAAAIy204AAAACXBIWXMAABYlAAAWJQFJUiTwAAABSUlEQVR42pWR0XKjMAxF+f+P6g/sbLJMkpIEkqbBBbKACSUp2MacikwfOn3ZWc3ckWRdXcty8PRLESU5iz8btvGZaHdiGUZsoiP7g+L38pnk+Ea42j3Ok6Nitd5L/cDL+cIi3BKu4wd3tUkI1nHB8tATHRsqfRd8cCk7LlWHllhfB+rWUDU9RSU1PVDo/sHTsy/fKQWV8Of+oHcTXXWnXWWkrzJtHJOmKSrPuaicIi+JT2+c0oLkVJCrkuw1o5Xaragw1wbTtgxNgx0GgnGC0ThsVlNsd+Txnrau6XWNsxbrHMYYnLN478CPTBJPo5Pc89MCJ4qiiX1vuYZLbirlI1Pc0zO26/inTXP39OW/C7az4EKeWnNWf2VsJ1OM/K8Fo0xtjMV0N6zW1Ne7fEKPcZ5BYL8wmJHBekaBF76XdXhZx+znix+5NXwCIv4VyibLESYAAAAASUVORK5CYII='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"source-tab","title":"","src":"/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png","srcSet":["/static/79da4e50c599e0226c48d5439368c947/0eb09/source-tab.png 500w","/static/79da4e50c599e0226c48d5439368c947/1263b/source-tab.png 1000w","/static/79da4e50c599e0226c48d5439368c947/77666/source-tab.png 1170w"],"sizes":"(max-width: 1170px) 100vw, 1170px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"그래서, 소스코드를 수정할 때마다 새로운 timestamp가 쿼리 파라미터가 브라우저에 넘어오고, 쿼리 파라미터 정보를 import.meta로 읽어 새로운 모듈을 가져와야 한다는 정보를 얻어 devServer에 요청 후 갈아끼울 수 있는 매커니즘을 가질 수 있었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"그렇다면, "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"await import()"}]},{"type":"text","value":" 동적 가져오기를 사용해 모듈 자체(예시: "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"Some.tsx"}]},{"type":"text","value":") 가져왔다면 react에서 적용은 어떻게 하는 것일까? HMRClient class의 fetchUpdate() 함수를 다시 가져왔다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// @vite/hmr.ts (간추린 버전)"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"public"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"async"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fetchUpdate"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"update"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" isSelfUpdate "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"if"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"isSelfUpdate"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"await"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"this"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"importUpdatedModule"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"update"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"return"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"for"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":" deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" fn "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"of"}]},{"type":"text","value":" qualifiedCallbacks"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"{"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"fn"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"deps"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"map"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","parameter"]},"children":[{"type":"text","value":"dep"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"=>"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"dep "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"==="}]},{"type":"text","value":" acceptedPath "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"?"}]},{"type":"text","value":" fetchedModule "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":":"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"undefined"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"}"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"qualifiedCallbacks"}]},{"type":"text","value":" 은 허용된 콜백이라는 뜻인데, 허용된 목록 안에 있는 acceptedPath가 모듈 path(dep) 와 동일하다면 fn을 실행하는 구조로 되어있다. 외부로 노출된 "},{"type":"element","tagName":"code","properties":{"className":["language-text"]},"children":[{"type":"text","value":"import.meta.hot"}]},{"type":"text","value":" 을 통해 콜백이 허용되었는지를 검사 후, 모듈을 교체하는 작업이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"이후의 동작은 Vite 공식 문서의 "},{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/features.html#hot-module-replacement","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"Hot Module Replacement"}]},{"type":"text","value":"를 통해 사용하고 있는 프레임워크의 plugin으로 이어져 동작하게 된다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"마이그레이션-결과","style":"position:relative;"},"children":[{"type":"text","value":"마이그레이션 결과"},{"type":"element","tagName":"a","properties":{"href":"#%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%EA%B2%B0%EA%B3%BC","ariaLabel":"마이그레이션 결과 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"vue-cli를 Vite로 마이그레이션 한 결과 devServer 실행 속도뿐 아니라 build 속도도 개선되었다. 아래는 GitHub Actions 빌드 결과이다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"vue-cli 빌드 결과"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 1136px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 9%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAACCAYAAABYBvyLAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAaklEQVR42i2NSxKAIAxDHRUURFrBH+rC+18y1uriTdJJJ6mWcoNywbRciGkXNpDoQDN4Lhh5lexUrCNYzx+/N68Kpo96V0mK/Ji10IcJdWPQtPZT06nvfJTyA+7/o1R0nPMhGSPQCheyjj6w4i7DTW5HkgAAAABJRU5ErkJggg=='); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"vue-cli-build","title":"","src":"/static/a261ab9d1208dfc27795f784d951b073/46e29/vue-cli-build.png","srcSet":["/static/a261ab9d1208dfc27795f784d951b073/0eb09/vue-cli-build.png 500w","/static/a261ab9d1208dfc27795f784d951b073/1263b/vue-cli-build.png 1000w","/static/a261ab9d1208dfc27795f784d951b073/46e29/vue-cli-build.png 1136w"],"sizes":"(max-width: 1136px) 100vw, 1136px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"strong","properties":{},"children":[{"type":"text","value":"Vite 빌드 결과"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-wrapper"],"style":"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 332px; "},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["gatsby-resp-image-background-image"],"style":"padding-bottom: 15.36144578313253%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAADCAYAAACTWi8uAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAoklEQVR42jVO2wqCQBRUd921495kV5OEfJGICoIgqB/o//9oWo/4MAwzcy5TCGVQN45R1S1KSSgFodJt1sRaNAaCLMqsK7X5e76yIMO8zhZkE66PNy63F6TOS4qgh44RvzPCc4K9jPD3E6S1MMuQ9RE0J+bDFDH+FsTPmYsUUju0vge5tDXcW+SPug8M6RyksezV3vFh0VqoznOmU4CKgRv+AUAjRTsUTpctAAAAAElFTkSuQmCC'); background-size: cover; display: block;"},"children":[]},{"type":"text","value":"\n "},{"type":"element","tagName":"img","properties":{"className":["gatsby-resp-image-image"],"alt":"vite-build","title":"","src":"/static/14daa32896955b7dc7db07782d7f4057/557e0/vite-build.png","srcSet":["/static/14daa32896955b7dc7db07782d7f4057/557e0/vite-build.png 332w"],"sizes":"(max-width: 332px) 100vw, 332px","style":"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;","loading":"lazy","decoding":"async"},"children":[]},{"type":"text","value":"\n "}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"14s → 5s로 약 62% build 속도가 증가되었다. Vite는 내부적으로 빌드 시 rollup을 사용하기 때문에 Webpack에 비해 더욱 빠른 속도로 빌드 할 수 있다. (devServer는 esbuild로 번들링)"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"br","properties":{},"children":[]},{"type":"text","value":"\n"},{"type":"element","tagName":"h2","properties":{"id":"마치며","style":"position:relative;"},"children":[{"type":"text","value":"마치며"},{"type":"element","tagName":"a","properties":{"href":"#%EB%A7%88%EC%B9%98%EB%A9%B0","ariaLabel":"마치며 permalink","className":["auto-link","after"]},"children":[{"type":"element","tagName":"svg","properties":{"viewBox":"0 0 16 16","width":"16","height":"16"},"children":[{"type":"element","tagName":"path","properties":{"fillRule":"evenodd","d":"M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"},"children":[]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"import.meta는 모듈의 메타 데이터를 저장하고, 활용할 수 있는 도구다. 이전에 import.meta가 없었을 때는 Node.js 환경에서 아래 코드와 같이 파일의 경로를 알아내고, 파일을 읽어올 수 있었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"js"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-js"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":"// Node.js 환경"}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" fs "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'fs'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" path "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"require"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'path'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" bytes "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" fs"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"readFileSync"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"path"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"element","tagName":"span","properties":{"className":["token","function"]},"children":[{"type":"text","value":"resolve"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"("}]},{"type":"text","value":"__dirname"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":","}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","string"]},"children":[{"type":"text","value":"'data.bin'"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":")"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"또한, 브라우저 환경에서 모듈에 대한 메타 데이터를 얻을 수 있는 방법은 아래와 같았다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"div","properties":{"className":["gatsby-highlight"],"dataLanguage":"html"},"children":[{"type":"element","tagName":"pre","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"code","properties":{"className":["language-html"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","comment"]},"children":[{"type":"text","value":""}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"data-option"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"value"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"text","value":" "},{"type":"element","tagName":"span","properties":{"className":["token","attr-name"]},"children":[{"type":"text","value":"src"}]},{"type":"element","tagName":"span","properties":{"className":["token","attr-value"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation","attr-equals"]},"children":[{"type":"text","value":"="}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]},{"type":"text","value":"library.js"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"\""}]}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]},{"type":"text","value":"\n\n"},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"<"}]},{"type":"text","value":"script"}]},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":">"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","script"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","language-javascript"]},"children":[{"type":"text","value":"\n "},{"type":"element","tagName":"span","properties":{"className":["token","keyword"]},"children":[{"type":"text","value":"const"}]},{"type":"text","value":" theOption "},{"type":"element","tagName":"span","properties":{"className":["token","operator"]},"children":[{"type":"text","value":"="}]},{"type":"text","value":" document"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"currentScript"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"dataset"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":"."}]},{"type":"text","value":"option"},{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":";"}]},{"type":"text","value":"\n"}]}]},{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","tag"]},"children":[{"type":"element","tagName":"span","properties":{"className":["token","punctuation"]},"children":[{"type":"text","value":""}]}]}]}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"하지만, Node.js 환경에서는 fs와 path 라이브러리를 항상 가지고 있어야 하며, 브라우저 환경에서는 현재 실행되고 있는 스크립트가 반드시 library.js 모듈일지는 불명확했기 때문에 문제가 되었다. 따라서 TC39에 import.meta에 대한 제안이 올라왔고 구현되었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"import.meta는 비교적 최신 문법이며, 따라서 구형 브라우저에서는 동작하지 않는다. Vite는 import.meta를 사용하기 때문에 자연스럽게 "},{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/#browser-support","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"구형 브라우저에서는 사용할 수 없다"}]},{"type":"text","value":". 하지만, "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/vitejs/vite/tree/main/packages/plugin-legacy","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"@vitejs/plugin-legacy"}]},{"type":"text","value":"를 사용한다면 가능하다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"또한, Vite의 "},{"type":"element","tagName":"a","properties":{"href":"https://github.com/vitejs/vite/discussions/8132","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"discussions"}]},{"type":"text","value":"를 보면 process.env 대신 import.meta를 사용하는 이유에 대한 답변으로 ECMAScript 모듈의 ‘새로운’ 표준이기 때문에 사용한다라는 답변이 있다. 물론 import.meta는 ECMAScript의 새로운 표준이기도 하지만 Vite가 개발 모드에서 브라우저에 모듈을 서빙하는 과정을 보면 브라우저 자체가 모듈을 다룰 수 있도록 하고, 빠른 번들링 및 모듈 교체를 위함임을 알 수 있다. 이는 Vite의 철학과도 연관되어 있다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"Vite로 마이그레이션 하면서 process.env대신, import.meta를 사용하는 이유가 궁금했다. 결과, import.meta MDN 문서도 함께 번역해 보면서 번들러가 어떻게 이를 사용하고 있는지 살펴볼 수 있는 시간이었다."}]},{"type":"text","value":"\n"},{"type":"element","tagName":"blockquote","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"p","properties":{},"children":[{"type":"text","value":"참고"}]},{"type":"text","value":"\n"},{"type":"element","tagName":"ul","properties":{},"children":[{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://www.proposals.es/proposals/import.meta","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"import.meta proposals"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://dmitripavlutin.com/javascript-import-meta/","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"How to Access ES Module Metadata using import.meta"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/import.meta","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"MDN - import.meta"}]}]},{"type":"text","value":"\n"},{"type":"element","tagName":"li","properties":{},"children":[{"type":"element","tagName":"a","properties":{"href":"https://ko.vitejs.dev/guide/","target":"_blank","rel":["nofollow"]},"children":[{"type":"text","value":"Vite"}]}]},{"type":"text","value":"\n"}]},{"type":"text","value":"\n"}]}],"data":{"quirksMode":false}},"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","fields":{"readingTime":{"text":"15 min read"}},"frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","userDate":"4 February 2024","date":"2024-02-04","tags":["Bundler","Vite","Environment"],"excerpt":"Vite의 철학에 기반한 방식 import.meta에 대한 이야기","photoAuthor":"Voicu Apostol>>https://unsplash.com/ko/@cerpow>>true","photoVender":"Unsplash>>https://unsplash.com","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/ba386/main.avif 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/8adb1/main.avif 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/dc6b3/main.avif 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}},"author":[{"name":"Pozafly","bio":"Frontend Developer","avatar":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#6808f8","images":{"fallback":{"src":"/static/8c061761f263c344f2c0416607c8adf1/73bb6/pozafly.jpg","srcSet":"/static/8c061761f263c344f2c0416607c8adf1/2f28c/pozafly.jpg 40w,\n/static/8c061761f263c344f2c0416607c8adf1/499f6/pozafly.jpg 80w,\n/static/8c061761f263c344f2c0416607c8adf1/73bb6/pozafly.jpg 120w","sizes":"100vw"},"sources":[{"srcSet":"/static/8c061761f263c344f2c0416607c8adf1/e73fe/pozafly.webp 40w,\n/static/8c061761f263c344f2c0416607c8adf1/61ca6/pozafly.webp 80w,\n/static/8c061761f263c344f2c0416607c8adf1/507b0/pozafly.webp 120w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":1}}}}]}},"relatedPosts":{"totalCount":2,"edges":[{"node":{"id":"e6258425-92a4-5f5c-8e75-b7cd70515731","excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","date":"2024-02-04"},"fields":{"readingTime":{"text":"15 min read"},"slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"id":"9257b05f-542a-5347-bbdb-81575de93244","excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","date":"2023-04-05"},"fields":{"readingTime":{"text":"33 min read"},"slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"slug":"/environment/why-do-you-use-import-meta-in-vite/","prev":null,"next":{"excerpt":"모던 웹 개발 생태계에서 CSS를 제작할 수 있는 다양한 방법이 있다. JavaScript 웹 프레임워크 분야는 거의 React가 대부분을 차지하고 있다. CSS 프레임워크(혹은 라이브러리)도 React의 영향 때문인지, 프로덕션에 CSS-in-JS…","frontmatter":{"title":"모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)","tags":["CSS","Performance"],"date":"2023-10-08","draft":false,"photoAuthor":"Michael Dziedzic>>https://unsplash.com/ko/@lazycreekimages","photoVender":"Unsplash>>https://unsplash.com","excerpt":"전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcICf/EABYBAQEBAAAAAAAAAAAAAAAAAAcFBv/aAAwDAQACEAMQAAABzEbqqcjgEzGUiQ81/8QAGxAAAgMAAwAAAAAAAAAAAAAAAwQBAgUABhL/2gAIAQEAAQUCxknXz9owKIt3G7M4qg+Ux0byVQPv/8QAIBEAAgICAQUBAAAAAAAAAAAAAQMCBAURBgASExRBFf/aAAgBAwEBPwG7zfA4q1mq17CLs17SV/k+CrX9jHXFrmJFtizKc7FWw6QmyCvVmpY8aj36cI80UYgjHpAI2BonQ+Df3XX/xAAeEQACAQQDAQAAAAAAAAAAAAABAgMABBESBQcT0v/aAAgBAgEBPwGXsqOBbbI5L3gkk9ljuFFvdwyLgKQVzA8R1ZH1udmU5ARylHs7kSc/Vf/EACQQAAICAQQBBAMAAAAAAAAAAAECAwQRAAUSITETInGBIzKR/9oACAEBAAY/AvSqSQGNVRpnss4WBGfgH/GGlcA5J4KcAd4yud5bZDfu7FtNmnSfdrZpx5t3IJLMUMccEhEqmsi2OQGYlkCWMPxL5HuB7Vs+QfB+9IcsGHhlZkYZ84ZGDD6PevVkjaWQjszSzS5+VeQqfgrjX6j+a//EABsQAQADAAMBAAAAAAAAAAAAAAEAESExQWGx/9oACAEBAAE/IaMOOpmZAB69oRT4BXgPmEc0tR9GAVbgzgUktD4w6aydgHYYuzq14YFmi0KixqEQABQUoCzPPk//2gAMAwEAAgADAAAAEMf/AP/EABcRAQEBAQAAAAAAAAAAAAAAAAERIQD/2gAIAQMBAT8QYd7v3iIPcXvQl/FoXUCUGLCpYXP/xAAaEQEBAAIDAAAAAAAAAAAAAAABESFRADFB/9oACAECAQE/EGRoZHE3Y+FAzoIlbLhUZca7hvzn/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAMUFh/9oACAEBAAE/EJsiZVLs8ZmdBLO3H/FAjzDjRSuUq/7vxJ3qkLHEcQSkA1AEAyvkA0MofXmFwxmYANAAEAAAAAgAAb//2Q=="},"images":{"fallback":{"src":"/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg","srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/6cce3/main.jpg 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/dec99/main.jpg 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/12c41/main.jpg 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/d2a19/main.webp 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/39bea/main.webp 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/8f28c/main.webp 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/237ec/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6682291666666667}}}},"fields":{"readingTime":{"text":"29 min read"},"layout":"post","slug":"/css/explore-how-to-apply-modern-css/"}},"primaryTag":"Bundler"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file diff --git a/page-data/index/page-data.json b/page-data/index/page-data.json index f776f2715..a6991abdb 100644 --- a/page-data/index/page-data.json +++ b/page-data/index/page-data.json @@ -1 +1 @@ -{"componentChunkName":"component---src-templates-index-tsx","path":"/","result":{"data":{"header":{"childImageSharp":{"gatsbyImageData":{"layout":"fixed","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAcDBgj/xAAVAQEBAAAAAAAAAAAAAAAAAAAGBf/aAAwDAQACEAMQAAABzQva40ELOEcQkgf/xAAbEAACAwADAAAAAAAAAAAAAAADBAECBQAGE//aAAgBAQABBQL0UyFDdpd1bL5LRxo5FNGQhpXi9IEH/8QAHREAAgICAwEAAAAAAAAAAAAAAQIDERIhAAQFBv/aAAgBAwEBPwH2PXm9TrJGsaQdaXaAWzuq6yZqGssmUVGbJDKRR4Pk+kQDIXzIBaiKyOzXP//EACARAAICAAYDAAAAAAAAAAAAAAECAxEABRIhIkEVMUL/2gAIAQIBAT8ByWSFZ3eUmaaMnUxHBS4U0i98QoJbUK9BSWx5JvlqXoVVDathsMf/xAAoEAACAQIEBQQDAAAAAAAAAAABAgMRIQAEEyIFEhQyUTFCUmFicrH/2gAIAQEABj8C5s1MkOygBI5z8iF9f4MDL8Gyr9PHbqpdsQN95c7a/SCRgMak+cleUncYlTkraw1Q7mnk0/UYjzvFZ5M+8i6qwtWPLJc20gzGTt97kfjW5CqAirZVUBVUWsFFhiNVr2hvFS1zj//EABsQAQEAAwEBAQAAAAAAAAAAAAERACExQXGR/9oACAEBAAE/IeHYbkNi8yxRF75noeMJgQF66ZGii5b3IQEK4ipYvg4MCvkguFPTw7g4HB1Hmgiga4HPxTgWIsKjHtZ8A4Gf/9oADAMBAAIAAwAAABB4/wD/xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMbH/2gAIAQMBAT8QJVgsOFuOoA4zyJbmWQETgqedJ//EABkRAQEBAAMAAAAAAAAAAAAAAAERIQAxUf/aAAgBAgEBPxCsLwy2CtDrY4hxVVLZS6QAALgAST3/xAAYEAEBAQEBAAAAAAAAAAAAAAABEQAhMf/aAAgBAQABPxBcTSzYF+gAcsIXKKklBqBnqI/NngCtchQV+CQiLzIgTRYqyGWJj8AMD5nDzB2B9mKjKoIFkKgWpbgP/9k="},"images":{"fallback":{"src":"/static/9fcf46c14997dbd0a642e9bf12069a20/de8d1/back5.jpg","srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/de8d1/back5.jpg 1920w","sizes":"1920px"},"sources":[{"srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/797d7/back5.avif 1920w","type":"image/avif","sizes":"1920px"},{"srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/d85eb/back5.webp 1920w","type":"image/webp","sizes":"1920px"}]},"width":2000,"height":1333}}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","date":"2024-02-04","tags":["Bundler","Vite","Environment"],"draft":false,"excerpt":"Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/ba386/main.avif 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/8adb1/main.avif 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/dc6b3/main.avif 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"frontmatter":{"title":"모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)","date":"2023-10-08","tags":["CSS","Performance"],"draft":false,"excerpt":"전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcICf/EABYBAQEBAAAAAAAAAAAAAAAAAAcFBv/aAAwDAQACEAMQAAABzEbqqcjgEzGUiQ81/8QAGxAAAgMAAwAAAAAAAAAAAAAAAwQBAgUABhL/2gAIAQEAAQUCxknXz9owKIt3G7M4qg+Ux0byVQPv/8QAIBEAAgICAQUBAAAAAAAAAAAAAQMCBAURBgASExRBFf/aAAgBAwEBPwG7zfA4q1mq17CLs17SV/k+CrX9jHXFrmJFtizKc7FWw6QmyCvVmpY8aj36cI80UYgjHpAI2BonQ+Df3XX/xAAeEQACAQQDAQAAAAAAAAAAAAABAgMABBESBQcT0v/aAAgBAgEBPwGXsqOBbbI5L3gkk9ljuFFvdwyLgKQVzA8R1ZH1udmU5ARylHs7kSc/Vf/EACQQAAICAQQBBAMAAAAAAAAAAAECAwQRAAUSITETInGBIzKR/9oACAEBAAY/AvSqSQGNVRpnss4WBGfgH/GGlcA5J4KcAd4yud5bZDfu7FtNmnSfdrZpx5t3IJLMUMccEhEqmsi2OQGYlkCWMPxL5HuB7Vs+QfB+9IcsGHhlZkYZ84ZGDD6PevVkjaWQjszSzS5+VeQqfgrjX6j+a//EABsQAQADAAMBAAAAAAAAAAAAAAEAESExQWGx/9oACAEBAAE/IaMOOpmZAB69oRT4BXgPmEc0tR9GAVbgzgUktD4w6aydgHYYuzq14YFmi0KixqEQABQUoCzPPk//2gAMAwEAAgADAAAAEMf/AP/EABcRAQEBAQAAAAAAAAAAAAAAAAERIQD/2gAIAQMBAT8QYd7v3iIPcXvQl/FoXUCUGLCpYXP/xAAaEQEBAAIDAAAAAAAAAAAAAAABESFRADFB/9oACAECAQE/EGRoZHE3Y+FAzoIlbLhUZca7hvzn/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAMUFh/9oACAEBAAE/EJsiZVLs8ZmdBLO3H/FAjzDjRSuUq/7vxJ3qkLHEcQSkA1AEAyvkA0MofXmFwxmYANAAEAAAAAgAAb//2Q=="},"images":{"fallback":{"src":"/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg","srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/6cce3/main.jpg 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/dec99/main.jpg 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/12c41/main.jpg 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/b56ea/main.avif 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/72ed6/main.avif 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/aa501/main.avif 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/c90a0/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/d2a19/main.webp 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/39bea/main.webp 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/8f28c/main.webp 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/237ec/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6682291666666667}}}},"excerpt":"모던 웹 개발 생태계에서 CSS를 제작할 수 있는 다양한 방법이 있다. JavaScript 웹 프레임워크 분야는 거의 React가 대부분을 차지하고 있다. CSS 프레임워크(혹은 라이브러리)도 React의 영향 때문인지, 프로덕션에 CSS-in-JS…","fields":{"readingTime":{"text":"29 min read"},"layout":"post","slug":"/css/explore-how-to-apply-modern-css/"}}},{"node":{"frontmatter":{"title":"ESLint로 import 구문에 규칙 넣기","date":"2023-09-06","tags":["Environment","ESLint"],"draft":false,"excerpt":"규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUGBAj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAgJ/9oADAMBAAIQAxAAAAHvHe+f5P0/BF+Ih//EABoQAQACAwEAAAAAAAAAAAAAAAMCBQABBBL/2gAIAQEAAQUC6GPkWPhM3zri0xvYTrybRVxDH//EAB8RAAICAQQDAAAAAAAAAAAAAAECAwQSAAURFDJBgf/aAAgBAwEBPwG1utZUqNXnLStXJurJE+C2ezPikRwU4dUVizEvzKX4I8QN/X2V+I/Gv//EACERAAICAQQCAwAAAAAAAAAAAAECAwQRAAUGEhMxISJS/9oACAECAQE/AavEdulijhsVN0SbBLXK12jIFYscI1KfxiXqvUhktwDBwQxBOpuEW0ldYPJLCGIjkeWtEzp8YZo/v0JHte7Y/R96/8QAKRAAAgECAwUJAAAAAAAAAAAAAQIDERIABEETMTJRkQUhIiNCU2KBkv/aAAgBAQAGPwLKwy7Ta513SBI0vLGNb3J5KBriiSLf7beCT8Pa3QHHCcZPtBp5LsnFPFHFapj8/ikPqvA7hQ7sUlo4+SKeld31ixXkpWouYtSuguqQvIVoNMf/xAAfEAEAAgIBBQEAAAAAAAAAAAABESEAYVExQXGBseH/2gAIAQEAAT8hOZJ8EwBJsnuWCWkJMbB+tY0N3gl+H7l5NnRrIoCaClVkpuNG7UlcKE5ydvOXQa9keUMArP/aAAwDAQACAAMAAAAQMC//xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMWH/2gAIAQMBAT8Q4O0KU9CJGmAMBgUAWqtWKDO7QfNF/8QAFxEBAQEBAAAAAAAAAAAAAAAAAREhUf/aAAgBAgEBPxBYdg6WI/aaU4gf8yz1NIiqAxf/xAAZEAEBAQEBAQAAAAAAAAAAAAABESExAKH/2gAIAQEAAT8Q0HMw9uc8VKcfFzB1TDpsLF4sQFMk23dfQ95nPAkThPFrXyLQQletTC1yUzDoTQO+UZGmJV7sU1EQB//Z"},"images":{"fallback":{"src":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg","srcSet":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/745053477406742b937cf317c03bd51c/2afe8/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/745053477406742b937cf317c03bd51c/62859/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671874999999999}}}},"excerpt":"프로젝트를 진행하다 보면 하나의 파일에 import 대상이 많아질 때가 있다. import 문이 많으면 어떤 모듈이 import 되었는지 파악하기가 쉽지 않고 지저분해 보인다. 위의 이미지는 Next.js 프로젝트의 파일의 import…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/environment/putting-rules-into-import-syntax-with-eslint/"}}},{"node":{"frontmatter":{"title":"GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys)","date":"2023-08-22","tags":["DevOps","GitHub Actions","Automation"],"draft":false,"excerpt":"restore-keys는 기존 캐시가 쓸모없어졌음에도 불구하고 기존 캐시를 불러오는 기능이다. 그렇다면, 무효화 되지 않은 캐시를 어디에 사용해야 하는 것일까?","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRtoAAABXRUJQVlA4IM4AAADQAgCdASoUAAoAAAAAJYgCdL1CScCMIDOJauZFWWvwAP7+fCRqJ1HSVO9tIR999fXyP/P57rC8REMKD1//0ioeS1//ZcuF7B+ofR9C21V2uWjaFEHZ/V9j/+YjqrWQX/oM//3/Xef38974//DpwZKlrsnStauDGxKwCIg6sCCzNEAE1v/+tZbF+e3c/dp8J2s0//xoH+/2b/MdD0ufroUYn//1ag//2gH//Wsf0DSlimwf/X6RG3r/0P/tmbftAf4hf79ZmYcMFl0JnQAAAA=="},"images":{"fallback":{"src":"/static/365cb7658cd8164573e7796d96f879bc/34dc0/main.webp","srcSet":"/static/365cb7658cd8164573e7796d96f879bc/3fe34/main.webp 750w,\n/static/365cb7658cd8164573e7796d96f879bc/da172/main.webp 1080w,\n/static/365cb7658cd8164573e7796d96f879bc/b3e28/main.webp 1366w,\n/static/365cb7658cd8164573e7796d96f879bc/34dc0/main.webp 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/365cb7658cd8164573e7796d96f879bc/8eada/main.avif 750w,\n/static/365cb7658cd8164573e7796d96f879bc/7c608/main.avif 1080w,\n/static/365cb7658cd8164573e7796d96f879bc/a357f/main.avif 1366w,\n/static/365cb7658cd8164573e7796d96f879bc/c62e1/main.avif 1920w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.5208333333333334}}}},"excerpt":"…","fields":{"readingTime":{"text":"19 min read"},"layout":"post","slug":"/dev-ops/cache-and-restore-keys-in-github-actions/"}}},{"node":{"frontmatter":{"title":"Next.js의 API Routes 코드 모듈화에 대해서","date":"2023-07-26","tags":["Next.js"],"draft":false,"excerpt":"API Routes를 사용하면 코드가 매우 지저분해진다. API Routes를 사용하면서 어떻게 하면 코드를 보기 좋은 형태로 남길 수 있을지 고민한 흔적.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRlABAABXRUJQVlA4IEQBAAAQBgCdASoUAAoAAAAAJQBOmUI4G2AKEr3kT9TfSAd8bMV4y7BHP9V/MDjAP1APvhp9S1P4WAaWWwAA/v//FO+/uU2wVgdvo3t7+/esHdVnt/ADvJNu//kKsryq7K4/kH6dQSpGZH/Wmy5Hn/aiP/iWMNYE/L04/fxOh6w6LNfMVCO2e4bk1w+gWtpgjXx8dPwxbP/af/3X+0eo//xh3vW8bP8x/59L+P+uAb/nTz0WLfd1P3vPtBSZEyy/3T0wbRrtQDgzQWJR+Ionuv+3z/+oMGf/VUBr79zfpXfp+qM/6uI1nkf8xYssVf+Jam3g3/89o/+0Ec/+2AL9tBfn9QixAvY/zPVrT+ICoP+ly+1C7/DtZUF9PQRI4d13mrIY7dR2bGTX2cQVs9OgNCzOMwQy1nvlPj56aTR9Kl6iaLrR7askCAA="},"images":{"fallback":{"src":"/static/6763177ee50addd67c4dc57952797f69/231da/main.webp","srcSet":"/static/6763177ee50addd67c4dc57952797f69/7513b/main.webp 750w,\n/static/6763177ee50addd67c4dc57952797f69/317ed/main.webp 1080w,\n/static/6763177ee50addd67c4dc57952797f69/b5c49/main.webp 1366w,\n/static/6763177ee50addd67c4dc57952797f69/231da/main.webp 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/6763177ee50addd67c4dc57952797f69/7f171/main.avif 750w,\n/static/6763177ee50addd67c4dc57952797f69/4f36a/main.avif 1080w,\n/static/6763177ee50addd67c4dc57952797f69/dac68/main.avif 1366w,\n/static/6763177ee50addd67c4dc57952797f69/f7ebe/main.avif 1920w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.5234375}}}},"excerpt":"메타 프레임워크 Next.js는 react…","fields":{"readingTime":{"text":"11 min read"},"layout":"post","slug":"/nextjs/about-modularizing-api-routes-code-in-nextjs/"}}},{"node":{"frontmatter":{"title":"글또 8기 회고","date":"2023-07-16T11:03:47.149Z","tags":["Diary"],"draft":false,"excerpt":"6개월 간 참여한 글또 활동 회고. 글쓰기에 대해서.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAACE3AAAhNwEzWJ96AAABGklEQVR42qVSu6qDQBDNB+mP2EY7u+AHKAZ8QCCmElvB1i6CpT8gCHYqCvoJqSVX0Bt3nbsrCIGLoMnCsMM5s2cPM3OAlTNNE3zCHdaKu677resalWWJsyzDRVHgqqowxSi3JvxPEGM837fb7cmy7CiKIpIkCZ1OJ0RzhmFGy7Ke77VbHE7n83m0bRvSNIXL5QKPx2P5CFRVHTc7XAR1XadOZiwIAmiaBoZhAIppmrZfkDxCi2CSJMBxHERRBI7jUIdot6BpmiMJaNsW4jgG0kMIwxCu1+tnDmmfBEEA13XB93243+/geR7wPA+Koox7p0x7+HM8HrFhGJgIYFmW55xgiHC7pwx93w9kB195nqP3ILv4otxmh9+eP5BhGA/5lJZDAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/53fe681b532753855e5826673a894e9a/44f99/main.png","srcSet":"/static/53fe681b532753855e5826673a894e9a/44f99/main.png 674w","sizes":"100vw"},"sources":[{"srcSet":"/static/53fe681b532753855e5826673a894e9a/23526/main.avif 674w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/53fe681b532753855e5826673a894e9a/15c6e/main.webp 674w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.56973293768546}}}},"excerpt":"퇴사를 하면서 함께 일했던 분이 글또라는 모임을 추천해주셨다. 글또는 글 쓰는 개발자 모임이자 커뮤티니다. 글또에 참여하게 되면 예치금을 미리 내고,…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/diary/geultto-8-retrospect/"}}},{"node":{"frontmatter":{"title":"React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법","date":"2023-07-02","tags":["React-Query","React"],"draft":false,"excerpt":"React Query의 mutation 실행 이후 클라이언트의 서버 데이터는 변경 되지 않은 상태이다. 화면을 업데이트 하는 여러 가지 방법을 알아보면서, 어떤 상황에서 어떤 방법을 사용해야 하는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRgoBAABXRUJQVlA4IP4AAABwBQCdASoUAAsAAAAAJZACdLcA/QBsgFQLeUqiUmPP/FX1K/7b+WXGAfpWYGrQH48nJYXAAP75Cef4pKYwXWaObmj6uNb89cRstuX4oguTI/Ltf2477JAiP5FcA5Tr9O5n03ruT+hCFEwnvbQf/BHc/uRzjYa2s/8HBWpoTqXuNry0nN2zBDiF4JKFyMGG9jBPudMl/UEj/9A9E9V8kEV9HbR8TPpZ8PjBDRgmL//WUX/9Jdyf/h8/0tv5zn9dUvP2bq/zO9JfbQv/fIzX9/LxVAn65Vaj3P/7mf+ZIZJg7Y5yEOa4AftMEfMZvKFetXih4WkIv3/k5M/oAAAAAA=="},"images":{"fallback":{"src":"/static/848a29a42bca253c5a3a44c252c3720f/81547/main.webp","srcSet":"/static/848a29a42bca253c5a3a44c252c3720f/73e0d/main.webp 750w,\n/static/848a29a42bca253c5a3a44c252c3720f/9fede/main.webp 1080w,\n/static/848a29a42bca253c5a3a44c252c3720f/81547/main.webp 1200w","sizes":"100vw"},"sources":[{"srcSet":"/static/848a29a42bca253c5a3a44c252c3720f/4814e/main.avif 750w,\n/static/848a29a42bca253c5a3a44c252c3720f/acf79/main.avif 1080w,\n/static/848a29a42bca253c5a3a44c252c3720f/30577/main.avif 1200w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"React Query는 데이터 fetching 라이브러리로 소개되지만, 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 쉽게할 수 있는 라이브러리다. 즉, React Query를 사용하더라도 실제 API 요청을 보내는 것은 Axios…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/react-query/mutation-after-data-update/"}}},{"node":{"frontmatter":{"title":"한영타변환기 Alfred Workflow 개발기","date":"2023-06-10T20:25:47","tags":["Tool","Alfred","Automation"],"draft":false,"excerpt":"dlfjgrp Tjwlseks akfdlek. dlrp sjan Qkrclseks akfdlek. zzzz...","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABkElEQVR42mWR61LbMBCF/QJMgeCr7rIdX8IkUEJDTSAkhJlO3/99To9s0obpj09ar1fnrLRRYkqY+QKq7pGaCokukdkaN8qhqFqY9hai7pCXDTRj1fSIbYlvhcaVtLhm3TmR8A365RrN4h7ad1CuhS57CD+ncIWUBqmukAUz5RFLD01z19CIZ0P+nCjmgdBVzOKQKCgiXYWcbpl0SJkfhUhu52NN2a9Q3d5BVd1o+EVwxoOBWPOKxkERoTRedjt8/PqN7f4dT7s9lpsBF5nEpTS4yOUUC/P/lW/OxLR18M7hx/oRx8MRh/cj3vYHcsTz6x7d6gHt6jv6uzX6+zVMsxjf8dRUIIq55J9ixhiUpcfrMJBnbB43eNr8xHbYYhhe0HZLGA7H1S0sB1b4GjPtvgpmXCQFrbWfhGtbFMoiI0mAXcR8z5nwuBYOV4JdMZdq1pjphn8FJT+MdaNQ2LWZDArmw2BSTjWQkFhMUw5xzv+K9ZJkjBM9CUfnYuNATkJkFDkh/hHywTA8UxAdzfW0/wGce/nh9L2hXAAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/24a1413e882f06cfbb3af834a3ff3897/252b8/main.png","srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/13110/main.png 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/6f9ad/main.png 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/bf69c/main.png 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/252b8/main.png 1556w","sizes":"100vw"},"sources":[{"srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/8038b/main.avif 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/bbbaa/main.avif 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/60776/main.avif 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/6812c/main.avif 1556w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/b665d/main.webp 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/71b9a/main.webp 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/9aed2/main.webp 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/cf8f0/main.webp 1556w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.4717223650385604}}}},"excerpt":"요구사항 문서를 정독할 때 때로는 타이핑해서 옮겨 적는 것도 큰 도움이 되는 편이다. 편집기랑 창을 양쪽으로 분할 한 뒤 이해한 부분을 타이핑 하다보면 한글 타자와 영어 타자가 원하는대로 타이핑 되지 않는 상황이 꽤나 많았다. 내 맥은 CapsLock…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/tools/alfred-korean-english-converter/"}}},{"node":{"frontmatter":{"title":"React 렌더링과정으로 알아보는 선언적이라는 의미","date":"2023-06-05","tags":["React"],"draft":false,"excerpt":"React는 개발자에게 코드를 선언적으로 작성하도록 한다. 이것을 렌더링 과정과 ErrorBoundary를 통해 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAgEBQn/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABweYFZJ8teBR//8QAGxAAAQQDAAAAAAAAAAAAAAAABAADBQYBAjH/2gAIAQEAAQUCjR2C5C+VWrQoix14okjVf//EAB0RAQACAQUBAAAAAAAAAAAAAAECEhEAAxMhMSL/2gAIAQMBAT8BsgwrtpJFmjyRqS6g+Vlkt1n5MPo6/8QAHBEAAgMAAwEAAAAAAAAAAAAAAQIDERIAEyIx/9oACAECAQE/AcAssm5QUV1EakdT7Mfpx90mCEINU72LyV5//8QAIhAAAgMAAgIBBQAAAAAAAAAAAgMBBBESEwUQAAYUITJD/9oACAEBAAY/AqNay40VrFpCnuWHaxSTYItNa/6MENkA2OR5Gx8o+Q+l/M2fJV7Nt9Ri7I8jCFL7FuNn2tTqcyN7acrIk6OlETG+gh9hzoVy64aw2QHLJLhBTMDyn8lMftkbuev/xAAZEAEBAQEBAQAAAAAAAAAAAAABEQAhEDH/2gAIAQEAAT8h6Fk+jilBsLYK5ITRA2JegnoZ+UgRRERGIjRE6I/HMu43R0mCBBaNCb//2gAMAwEAAgADAAAAEHAP/8QAGBEBAAMBAAAAAAAAAAAAAAAAARARIUH/2gAIAQMBAT8QDTk8RMdrFFsyB//EABcRAQEBAQAAAAAAAAAAAAAAAAERECH/2gAIAQIBAT8QXztwF1ZZogCVYv/EABcQAQEBAQAAAAAAAAAAAAAAAAEQEQD/2gAIAQEAAT8QaMl/Oh0+QwzMmgdfPJ2GwkqLnvDiAABBEQRE4KSc7UqTatEMf//Z"},"images":{"fallback":{"src":"/static/776ea9d9adf27d1450842a29d5b85c8c/a764f/main.jpg","srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/37bba/main.jpg 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/61c72/main.jpg 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/d61e8/main.jpg 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/ba386/main.avif 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/8adb1/main.avif 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/dc6b3/main.avif 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/a66aa/main.webp 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/65dd5/main.webp 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/4fad6/main.webp 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"라이브러리와 프레임워크 “The library for web and native user interfaces” (웹 및 네이티브 사용자 인터페이스용 라이브러리) 새로 개편된 React 공식 홈페이지에 있는 문구이다. 개편 되기 전 React…","fields":{"readingTime":{"text":"17 min read"},"layout":"post","slug":"/react/declarative-meaning-of-react-rendering-process/"}}},{"node":{"frontmatter":{"title":"React는 Hooks를 배열로 관리하고 있다","date":"2023-05-27","tags":["React"],"draft":false,"excerpt":"왜 Hooks에 이런 제약 조건을 걸었을까? React 내부에서 Hooks를 어떻게 처리하고 있는지, 이렇게 디자인 된 이유는 무엇인지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQGB//EABcBAAMBAAAAAAAAAAAAAAAAAAIEBQf/2gAMAwEAAhADEAAAAciWdzbSDsCKIjn/xAAaEAACAwEBAAAAAAAAAAAAAAAEBQEDBgIU/9oACAEBAAEFAiWbCWhZcaMvvWhVL/Qs5tfmjBZse/c6uv8A/8QAIBEAAgICAgIDAAAAAAAAAAAAAQIDBAUSERMAMRQVIv/aAAgBAwEBPwHuy0VcWslbj+zrsKVcpM3XlzGw+OZVGPqGMc7flllZW0Cu7WNHiy2kaI8eRhdVCvFDJN0xuOA6RaOV6gwYR8ek19Hz/8QAHxEAAwEAAgIDAQAAAAAAAAAAAQIDBBITBREAFENS/9oACAECAQE/AfXjbztLIghnlP7KaNEBWsy8hnciGXVqbnBnZgtlgKCZ5Tn1N8fNiR2Q+OrfgxXulLD104kAMncnbxIH6haf2iN7Vf/EACMQAAICAQQCAwEBAAAAAAAAAAIDAQQFBhESExQiACEyIyT/2gAIAQEABj8CZPZSQyzWxOOswGTgSH/DpAvN4znyl3YMU/7MaddbOa4gYQHkHh7Wes0kYzDZqLa1NqpoW7OJDUbacQ5+oPEuMJM9Kzhv5IuiS92qwte7qDU67FXHMrmiulwJrdeVyeyAkdUUu2B33hkp32KA9ICFLbTSsvGtY9KrGSm5kGkdV9LR83MX4zBBi/FfaDhYXPBkWJFcdff8sJRfOsVVuIVVQJZFgsGoOp+FhfPktUx08wBkQQct/swAYLJUrdy6IWbtVz2X0VylwXbDuPWbFfQoemI4AK4j1H8z8//EABgQAQEBAQEAAAAAAAAAAAAAAAERADEh/9oACAEBAAE/ITx0G3wiSFZPGOYVO15TG2ShwhP/ALZwYOCLAH6xLFHJWuGyQixYPJQ1yGGhxB7u7E6VFeYBXH//2gAMAwEAAgADAAAAENgP/8QAGBEBAQADAAAAAAAAAAAAAAAAAREAITH/2gAIAQMBAT8Q0172QEviCR52c2FXwwpowfAgIf/EABgRAQADAQAAAAAAAAAAAAAAAAEAESEx/9oACAECAQE/EFHMmO7MLFgb9EzQudAjkFDWBv/EABYQAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAQABPxAMfwZF4vv+q3sVpyafabL76goYIhZaY/4fAZLG+ewVBNJiX2wyAhyCFMxF4qdqCGxqUZ//2Q=="},"images":{"fallback":{"src":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/4d5c4/main.jpg","srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/4d5c4/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/80a20/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/ffef7/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.75}}}},"excerpt":"React는 Hooks을 배열()로 관리하고 있다. 이는 Hooks를 관리하고 있는 배열에 index로 접근할 수 있다는 뜻이며, 이는 호출 순서에 의존하고 있다는 뜻이다. (아래에서 예시로 든 코드는 보기 쉽게 Linked List…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/react/react-is-managing-hooks-as-an-array/"}}},{"node":{"frontmatter":{"title":"왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까?","date":"2023-05-09","tags":["TypeScript"],"draft":false,"excerpt":"TypeScript void 타입을 조금 더 알아보기.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAcBAwYI/8QAFgEBAQEAAAAAAAAAAAAAAAAABgIJ/9oADAMBAAIQAxAAAAFV827OdRxlosxJH//EABsQAAMBAAMBAAAAAAAAAAAAAAMEBQIBBgcS/9oACAEBAAEFAiJzxed6toA12W0paqJXWAIlqa3wff0T/8QAHxEAAgICAQUAAAAAAAAAAAAAAQIDEQAhEiIjMUGB/9oACAEDAQE/AW4vrQ7caNY5ElUVS3it0fePCkjNI9lnJZiOmydk0tAfBn//xAAcEQADAQEAAwEAAAAAAAAAAAABAgMEBQAREzL/2gAIAQIBAT8Bw8rs5H6C0pXRHT1OlriRvOaU8+zZfRKKJJDUMkqIHLH39RRkZVZUXn8+WHBixIGCZMufOgetLsFjJEUG1matSAvr6UZnb9MSfP/EACgQAAIBAwMCBQUAAAAAAAAAAAIDAQQREgUTIQAUFSIxQbFRYWNxgf/aAAgBAQAGPwLQ6ypNu8zWtb7dKjUe5tpo926xyaGMAESTNvli8IMNw1gfhpNXx5Nx+Z/bLMeT5tjb6e43LUaOhnT1OpKAJpScT8GU1GmmZZh+chKVZDlMzETa8+vS6GUU7UKY1oTO8p134ZiTadypYu4RIAzMQmSkYjIr37Sit+RROn95sZJTPx6R0RYiN/YImB/kXn56/8QAGhABAQADAQEAAAAAAAAAAAAAAREAITFBUf/aAAgBAQABPyFgE3wgi0ZYqwW8GWCgPqLUQJSOuXaYcHdXocBKdzvIjLCDAWkpkgGoADU02A+rpwM6o9SJ9opeu21z/9oADAMBAAIAAwAAABCQ7//EABoRAQEAAgMAAAAAAAAAAAAAAAERACExQXH/2gAIAQMBAT8QmDU7wKQgWgqIteK8NUBcBXO4AXzP/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAh/9oACAECAQE/EJXi2BlnEVKwWMAFxc74bFqv/8QAFxABAQEBAAAAAAAAAAAAAAAAAREAIf/aAAgBAQABPxCbD0xshesT6MATaBCRMug8QbrHlzLcfZdbU8WfJ+A6cYFfKjWvsw9CZ9FQAGZzrVsZaPKEnoCCB//Z"},"images":{"fallback":{"src":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/8ad6a/main.jpg","srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/8ad6a/main.jpg 637w","sizes":"100vw"},"sources":[{"srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/0a6a0/main.avif 637w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/85b8e/main.webp 637w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671899529042387}}}},"excerpt":"void의 기본 선언 방식 void는 TypeScript에서 흔하게 사용하거나 추론되는 타입이다. 주로, 함수에서 이 없을 경우 return 타입으로 void…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/typescript/why-can-typescript-return-any-value-using-void/"}}},{"node":{"frontmatter":{"title":"TypeScript의 기본개념과 환경설정","date":"2023-05-05","tags":["TypeScript","Environment"],"draft":false,"excerpt":"TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMElEQVR42mP4////v38oiHjAANKMikjTjAaA+v+imvH3H27NNbufm0+/5Tb/rvPcOw5z7px9+g0o+Psv1JR/MBMxnQbS7L/wLkP2aZbiswwFZxiKz2658fHll98/fv/7B1YLpO+8/fnjD8iYX3/+AQ399usvQrP3onsGU25mbHwcsPS+xYxbyy6+33X747bbH1ddfT///Ntll9/3Hn+14cYHIHfllffTTr/ZdPMjxC0gzW4L7ir3Xs/Z8iR+7aO6Pc833/j4/fe/vfc+A/UffPD5xJOvF55/O/X065VX388//7bxxscH739CQgGk2WvhPa66i46z7wCtLdj6dN/dz0BBoH6sYYnu54cffl588R2Irr36DgytTz/+QiMfHGCQMEMgpLTAgCsOiUktDP8pAAA9+2KaOzXrLQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png","srcSet":"/static/e092969a3269e232f50e03e941f3d22f/38824/main.png 750w,\n/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/2f802/main.avif 750w,\n/static/e092969a3269e232f50e03e941f3d22f/820f8/main.avif 800w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/24bb5/main.webp 750w,\n/static/e092969a3269e232f50e03e941f3d22f/a78a0/main.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5475}}}},"excerpt":"TypeScript를 사용해 개발 하는 단계는 크게 3가지로 나눌 수 있다. Lint stage Compile stage Runtime stage Lint stage는 개발자가 코드를 작성하는 시점이다. Compile stage…","fields":{"readingTime":{"text":"16 min read"},"layout":"post","slug":"/typescript/typescript-env/"}}},{"node":{"frontmatter":{"title":"JavaScript MVC 패턴으로 만드는 SPA","date":"2023-04-17","tags":["JavaScript","Design Pattern"],"draft":false,"excerpt":"모던 JavaScript 프레임워크 없이 MVC 패턴으로 SPA을 만들어보자","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAcGCf/EABcBAAMBAAAAAAAAAAAAAAAAAAMFBgf/2gAMAwEAAhADEAAAAejWSqkKItsIj9K//8QAGRAAAwEBAQAAAAAAAAAAAAAAAQIEAwUR/9oACAEBAAEFAtZBllDfJ09EjXy52GXJASoE+f/EACMRAAIBAgQHAAAAAAAAAAAAAAECAwURABITMQQGFCEjYdL/2gAIAQMBAT8B5W42CStpTZEbp3iIlGkjsXALo0baiFO4s984tsmY3DUalXPhbf19Y//EACIRAAICAQEJAAAAAAAAAAAAAAECAwURIQAEEhMjMWFxkf/aAAgBAgEBPwGxinNZNvcbATxlWhPMZVCllVw4EbcWjHAGMnuwA1FjZYHWT568bf/EACMQAAICAQMDBQAAAAAAAAAAAAECAxEhABIxBBATIiMzUfD/2gAIAQEABj8Cknm+OJGd7IUUPsnA/DHOm6dIirQjd5vCY0KjFFx7bE36cknXOnW8FSCMURXB1NEgCR772IAi3xdLQuu3/8QAGRABAQEBAQEAAAAAAAAAAAAAAREhMQBB/9oACAEBAAE/IV6j0AO1YB3UGDahhLNfhFLgYAFFlQkjwS4spCEE0TEcTvrAeu37SThUsznhAF4e/9oADAMBAAIAAwAAABAEz//EABoRAQEAAgMAAAAAAAAAAAAAAAERADFBofD/2gAIAQMBAT8QZloxFp3BGG5Etiak5RR870n/xAAbEQADAAIDAAAAAAAAAAAAAAABESEAMUGx8P/aAAgBAgEBPxAxiUbeESFkAQMWBCg67Px5z//EABkQAQADAQEAAAAAAAAAAAAAAAEAESExUf/aAAgBAQABPxDRnqoVcsCvthYHqoFiJoAIus458RarRw4mPl28lZdoMBAjjZIQIy7NKcqgfWLBkmIUkFAc4T//2Q=="},"images":{"fallback":{"src":"/static/5349dfe902fbdb7676264f2e7aae8a83/3440d/javascriptMvc.jpg","srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/3440d/javascriptMvc.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/3d183/javascriptMvc.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/17574/javascriptMvc.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"모던 JavaScript 프레임워크는 여러 패턴을 따른다. MVVM 패턴, Flux 패턴, Component 패턴 등. 다양한 문제를 해결하기 위해 다양한 패턴이 생겨났다. 이번에는 예전부터 사용되어온 MVC 패턴을 JavaScript…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/javascript-mvc/"}}},{"node":{"frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","date":"2023-04-05","tags":["Bundler","Webpack","Environment"],"draft":false,"excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/885fa/main.avif 750w,\n/static/398ff7eccce15fa106b9755da8007778/4f36a/main.avif 1080w,\n/static/398ff7eccce15fa106b9755da8007778/dac68/main.avif 1366w,\n/static/398ff7eccce15fa106b9755da8007778/97f05/main.avif 1720w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}},{"node":{"frontmatter":{"title":"노드 버전 매니저 툴 비교기(nvm & fnm & Volta)","date":"2023-03-28","tags":["Tool","Node.js"],"draft":false,"excerpt":"nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAYIB//EABYBAQEBAAAAAAAAAAAAAAAAAAgABP/aAAwDAQACEAMQAAABzdRanF4HOXiqjdf/xAAbEAADAAIDAAAAAAAAAAAAAAADBAUABgIRM//aAAgBAQABBQKXc4P7FIdqB2RnTm2DzwADY9C9Z//EACERAAICAQIHAAAAAAAAAAAAAAECAxESADITISNBUWGz/9oACAEDAQE/AZHEsTBC2fGYHMclUBdhSQWbJ3qwpvKhj1u01ehFAB8tf//EAB4RAAICAgIDAAAAAAAAAAAAAAECAwQREgUhAAZC/9oACAECAQE/AWkq05ZVjoxtBZ4uvC4lkZ2FrJaWwgIwm/QUbnTTYDZ8ovt/LIqosihVAVRonQGAPnz/xAAjEAADAAEDBAIDAAAAAAAAAAABAgMRBBITAAUhURAxFGFx/9oACAEBAAY/ArdgoITYNecaz1ILcqY4E1ClSsucnaMMcMUUgbsjufJPWfgsmpEeS6WkaPSWx1k52wWa7wNmWxkZOerVfuFjvrRlHGmFVnLBFxjCrnx095Qit3oGa3FM23DOGWpUvNv2jKfA9Dpqvg0fyzYAyffjA/vv7+/j/8QAGhABAQEBAAMAAAAAAAAAAAAAAREhADFRcf/aAAgBAQABPyGd8BiLfFbtzXdG5MsdLkmOVS+8BSA3cAogn3XgYaEioKRBuNFwWKV1y0UGjCg1VUvR67//2gAMAwEAAgADAAAAEMPf/8QAGhEBAQADAQEAAAAAAAAAAAAAAREAITFRof/aAAgBAwEBPxAexpMR3yonIOcd3TtAgowABz7emf/EABgRAQEBAQEAAAAAAAAAAAAAAAERADHw/9oACAECAQE/EFrNNxOKAECFJguX5iMAXwHy7//EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxYf/aAAgBAQABPxBOeyTtu7phz5c5dwE8139VQEMhMbyGwbLNpFBZpWuvKq2XlKc0Mv4kmwLUoPi3fJ3/2Q=="},"images":{"fallback":{"src":"/static/fa6657a7573785fcabeb321f5d546e59/3440d/node-version-manager.jpg","srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/3440d/node-version-manager.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/3d183/node-version-manager.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/17574/node-version-manager.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"모두 Node.js의 버전을 관리하는 툴이다. 가장 먼저 nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다. nvm 먼저 nvm…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/node/node-version-manager/"}}},{"node":{"frontmatter":{"title":"다시 보기 위해 적어두는 URI 구조","date":"2023-03-16","tags":["Network","URI"],"draft":false,"excerpt":"하나의 주소 안에도 여러가지 용어가 나온다. Host, Domain, Site, Origin등이 그것이다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABQAGB//EABcBAAMBAAAAAAAAAAAAAAAAAAQFBgf/2gAMAwEAAhADEAAAAe1oHMaIvZsVU4f/xAAZEAADAQEBAAAAAAAAAAAAAAACAwQBEyP/2gAIAQEAAQUCfZlsi5jaHsClyTPR2coSrpzf/8QAHhEAAwABBAMAAAAAAAAAAAAAAQIDBAAREiEUIzH/2gAIAQMBAT8BzVrjeEZCcBbDjf1sXYsWIFCaTJSjFN2EzxXrie21sx73+6//xAAhEQACAgIBBAMAAAAAAAAAAAACAwEEBRETABIUFSExQf/aAAgBAgEBPwH18561lJrW2bx+XZjLC7ioUsVgC7DV1vFYXKsV21ClliBMy5eQBEVbDDmILGbHyAAEzAzqZARGZ+/3t31//8QAJRAAAQQBAwQCAwAAAAAAAAAAAQIDERIhAAQxBRMUIkFRUmFx/9oACAEBAAY/AmnvN7Dw6g7tfD9bvdu4umh7qSipXlJbUnnJTqUM9WdTYpvCVIvE1JG1A5zAhX7GmEUdKkNUX6qJshxxJCpk2xmc63G6caB3G1fhh0FSFN2UEqihTMjBtOqNvPIRN6h1ytvyraLY551h5z75+Tyf7r//xAAbEAEBAAMBAQEAAAAAAAAAAAABEQAhMVFBYf/aAAgBAQABPyEmEq4KpKTB+gIidAWmowEigA1oc9kSC6gCIhp+5E9lxag1bA0yesUuZOy4OeO4xitUe0VPU7V2vc//2gAMAwEAAgADAAAAEFDf/8QAGxEBAAICAwAAAAAAAAAAAAAAAREhMUEAYXH/2gAIAQMBAT8QCn4qqJsWViCSOYK2WMrbo30ec//EABgRAQEBAQEAAAAAAAAAAAAAAAERIQBB/9oACAECAQE/EHaeIKbsX3YE3C7MtAO0O1otS+9//8QAGBABAQEBAQAAAAAAAAAAAAAAAREAITH/2gAIAQEAAT8QI6tAWWqOJOKHD5dc9V9LDQPIxGBss3rElxwNYqu6gF9VPypFaCMZplJFSGB8QAGKqOFWcnUmshUu/9k="},"images":{"fallback":{"src":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a764f/main.jpg","srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/37bba/main.jpg 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/61c72/main.jpg 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/d61e8/main.jpg 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/ba386/main.avif 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/8adb1/main.avif 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/dc6b3/main.avif 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a66aa/main.webp 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/65dd5/main.webp 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/4fad6/main.webp 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"프론트엔드 개발자로 일하면서 다양한 네트워크 용어중 주소에 대한 용어가 항상 헷갈렸다. 하나의 주소 안에도 여러가지 용어가 나온다. , , , 등이 그것이다. 이전에 토이 프로젝트를 호스팅하기 위해 도메인을 구입하고 AWS…","fields":{"readingTime":{"text":"11 min read"},"layout":"post","slug":"/network/uri-structure-written-down-for-replay/"}}},{"node":{"frontmatter":{"title":"React의 클래스형, 함수형 컴포넌트 차이","date":"2023-03-05","tags":["React","JavaScript"],"draft":false,"excerpt":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsSAAALEgHS3X78AAACf0lEQVR42i2STU8TYRSF+xPc+ANc+A9cundjXBl0oTHuXKorE43RoAtNCBWQj0KBClRKQQSK2A86ZdpSoGWGKYXSgkSQsEHQ8g3t9PHO4OIm73nvzH3PPec4ynor1UI/Zt5LxTpnXbDqg6KX6oKF2wUPwErfBV50Cx4U3Cu4BVNwteDDXPJQ1ppxIKCSdWPKx6d6G0dGN8eZVkrT9eynWwV7OEy3cDDTwJHWzqHWyX6qkf2E9OfaOMt2YsqjNrF8Hw5z5TMYLnYSTuKJcUIplZHQGNFZFdWYJzitEggHpMYIpuLEs7rcZ1AWMqj5PGpygl21DnKdVIv9OM7nm2G5i7mYj8wZjLhq6a65SrT4g0IFFD1HdOO3XYqxjFE6Ibm+SWB8iK/9LobDQWbjQyJBD+cLLmFotAtlN4Ye5vvPXRpuXSF+5xLOV48JG0tE17cJlGDsD0zKuTcyhdvvo/XZPd7cvUbTk9tEQqK5aGmt7WDVTzndgJ4O4M8s0/fyAZ7n94nkVoTJL0LFTcZl4OhfGbi2hV9J8PBtHZdv1nD9xTuetnxiPvmF8ly9bY5o6AW9kUzMy0hug4is1jM1R2Jrm0K5QnRhGWVjh0mpWDbPYumY2sEJbrx28mgwxvuIRjrUJQxdmEWfpeFHOxJ7mgdVGWY0/E2MmBLxNWLaDMGkwng0SGBygon4JHExJLVkoM6nUGZUlLCPvYzbjlpZk5UrImTVYlnwcjLr5HC2iWOJzkGmjf1kvY2Psh6OdDcHqQ92ZA41t90vJZ2cWqauXeSwordYGg7YppSFqZnvlaafas5th5hCn43JdvzH8vDagIS7A9Nok/D3U5X/LTOsYRaxfy7ok/GBEcEZAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/eaa081aa6f5f962aab7f962d4692e442/62ea7/class-functional.png","srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/62ea7/class-functional.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/f1cd5/class-functional.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/2fa07/class-functional.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5}}}},"excerpt":"react의 class, function 컴포넌트 차이 Class 컴포넌트 Class 컴포넌트로 Counter를 만들어보자. react 라이브러리에서 제공하는 Component를 import 받아와서 상속 관계를 맺어주었음. 따라서, react…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/react/class-functional-component-difference/"}}},{"node":{"frontmatter":{"title":"객체지향 프로그래밍으로 알아보는 prototype","date":"2023-02-24","tags":["JavaScript"],"draft":false,"excerpt":"자바스크립트가 만들어진 기반, prototype 언어가 가지는 근본적인 철학에 대해 고민해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAYIAQn/xAAWAQEBAQAAAAAAAAAAAAAAAAAEAQL/2gAMAwEAAhADEAAAAeH9vQC4HymGlR//xAAcEAABBAMBAAAAAAAAAAAAAAADAQIEBQYHExX/2gAIAQEAAQUCro7JMvKtZUldrdWvegTGE42SXvnCTon/xAAfEQEAAgIABwAAAAAAAAAAAAADAQIEEQATFCEjsdL/2gAIAQMBAT8ByuqU8eowNRFIRPIpMr3bu63rS8tA4xqJYdrHipZec1ZYyQ4gdRuqb1G9Xr8T7nj/xAAfEQACAgEEAwAAAAAAAAAAAAABAwIEEgARE1EUI/D/2gAIAQIBAT8BMZngxsFBW/N4FZNgWqwQ6HhgtlE1OSwxFidtIlYgK/DD1uaDnt93se9f/8QAJBAAAwABAwQDAAMAAAAAAAAAAQIDBBESIQAFEyIUMUEGUYH/2gAIAQEABj8C2ZG7Rpz8KH1d+AyvwjhozgKUp97kA4dtB12z+R9s7lLuWZXIfMfMxBR8H4VaY0fhoCC8FlbLm+LO8/K4+XW7I+kEQym3C6PtG5S4ZtSNeV426jn2BOuh0EaSrRKY7StB1YhpV3j3Q6+p9E+v66t2le55M+25OTLKvgyKxxnssZuD4pKiqnkAoZIFi1QKMhcBumZ9Sd553N+6Mfo/rMT/AL1//8QAGhABAAMBAQEAAAAAAAAAAAAAAREhMQBBYf/aAAgBAQABPyHebPfjkkCtuRypmwVKmDQzuRJw5JLlhMJ2pQOJ2iI9MKWNQIwbIpgaMpsYHC7ySD7QZxBYvq7/2gAMAwEAAgADAAAAEDzP/8QAGBEBAQEBAQAAAAAAAAAAAAAAAREhADH/2gAIAQMBAT8QaswvAJb0iLpLsDoBFhUFgdlTyq17/8QAGREBAQEBAQEAAAAAAAAAAAAAASERMQBR/9oACAECAQE/ECYYww/XCiE/ZdMQ7vF+DUQoQAgBD//EABkQAQEAAwEAAAAAAAAAAAAAAAERACExEP/aAAgBAQABPxCyXz81zDXQ3wbfOHxxtRg0YJyqfnu2GKzB36Ui0YLQlk9CLgfu6kvMIP4Fmmr4KVUKVkKVZeB//9k="},"images":{"fallback":{"src":"/static/3742ab40c4a37d6d517fd4a6db47a830/d097c/main.jpg","srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/37bba/main.jpg 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/d097c/main.jpg 850w","sizes":"100vw"},"sources":[{"srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/ba386/main.avif 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/3d8d8/main.avif 850w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/a66aa/main.webp 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/873af/main.webp 850w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5623529411764706}}}},"excerpt":"객체지향 프로그래밍 객체 지향 프로그래밍(Object-Oriented Programming, OOP…","fields":{"readingTime":{"text":"22 min read"},"layout":"post","slug":"/javascript/prototype/"}}},{"node":{"frontmatter":{"title":"Event Loop와 비동기","date":"2023-02-16","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. await 키워드를 만나면 async가 붙은 함수 전체가 MicroTask Queue에 담기는 과정까지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAQUAAAAAAAAAAAAAAAAAAAEDBwgJ/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQX/2gAMAwEAAhADEAAAAcOpgrUlkaAjP//EABsQAAICAwEAAAAAAAAAAAAAAAEEAgUAAwYh/9oACAEBAAEFAqCgZ6BpvjdFEvkCRKR9z//EABwRAAICAwEBAAAAAAAAAAAAAAECAwQREhMQMv/aAAgBAwEBPwGq8kF0WJDFPWX5qPChBfC4Lu/QOu2Sy8xsjaqY3US+f//EAB0RAAMBAAEFAAAAAAAAAAAAAAIDBAEABRIUFSL/2gAIAQIBAT8Bnu6dPHoeqxt+qavzXU6wAYZnuNXGaSn+UaKexgsMSw6FOW4k7Nz/xAAlEAACAgAFAgcAAAAAAAAAAAABAwIEAAUSEyEQERQVMUFxkbH/2gAIAQEABj8CZVqk61q3StNexcttGoR0VKNWDLFpnPcxgAIwBlKQGGDMWU7VjbLb0XWp5fcyFPh5sQqxlrpLs+Z2W6RCvtvA4URGU5yhgEEgjkEHsR8EcjB/ff79en//xAAbEAEAAgIDAAAAAAAAAAAAAAABESEQMQBBYf/aAAgBAQABPyFsXWo8jFj8nVtuKuYqFMmIYtB/zSZxpUJ6JxF1lWVWltVWXtWXH//aAAwDAQACAAMAAAAQlA//xAAXEQEAAwAAAAAAAAAAAAAAAAABACEx/9oACAEDAQE/EA7KIoM77buHBP/EABYRAAMAAAAAAAAAAAAAAAAAAAEQMf/aAAgBAgEBPxCU+3KzBB04RV//xAAaEAEAAgMBAAAAAAAAAAAAAAABEBEAITFh/9oACAEBAAE/EOEHTHdeoqBTJ+EATyAXZG1kj3t1w1rxT3G1Oo3lt5dVRFVVY//Z"},"images":{"fallback":{"src":"/static/e2f3938297514483cd217adbed0eb153/3440d/main.jpg","srcSet":"/static/e2f3938297514483cd217adbed0eb153/3440d/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/e2f3938297514483cd217adbed0eb153/3d183/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e2f3938297514483cd217adbed0eb153/17574/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"요약 JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. Event Loop는 JavaScript Runtime Environment에 있으며 Web API와 Call Stack…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/event-loop-and-async/"}}},{"node":{"frontmatter":{"title":"JavaScript의 Symbol에 대해서.","date":"2023-02-15","tags":["JavaScript"],"draft":false,"excerpt":"Symbol은 도대체 뭘까? 어디에 사용되고 있을까? 조금 더 깊게 들어가서 알아보자. 나중에 라이브러리를 만들 수도 있으니..","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6klEQVR42k2SW0/iUBSF+wuUUkqBci/Xckc7eIEQQEcBqa3MixMd541hEoOO8Ufoo/5hv842xOQ0Weecvddea/UoppnSND2VyiSTaUAikUyns/G4KUDXje0thwCWYcTZApRyuXpz8wuKXM4CNJtt7o6O+oBoNOa6l7e3wW0+X+j1DqVnPD5hC1ZqtcZ6/RfWQqH09vY+GAwZtVhcUkrz4+O/l5dXVLRanfv7TSyWyGbzm82Dbdc5VPhCobDoQSRDUCvCAOFwZHdXBbClkhowpJ+yq9Xa2dmUI9pGo0mxWAYcHBzigjl7ew5aDCNRKlXG4wll9Mxmc8v6LxsBeKABYk7r9SY9FxeueKbZ83wAsn1/CSMGff/KtmufshH2NUbot7FHIlEWV7Crqia3W3cKOlerP5ZVhPLp6bnd7lI9mZxggZPz86nnXTGwUrHv7n7LZH4BQgBKt7t/ff1Twlit1p1OF5Gk0Gi0mOO63nL5A8PMmE5n1JD26el3WALPEOzshEQ2bbBkMjlNi+IcYaoaIXCJWvSzADIskD0cjvDAms8XvBmcHx8PCEzXY47zjbQh5af0+wMYAejHXSAbGUiVB+g4PTHPy4FUACz0sAUwkLcFCxQMU74+WookT4okT4DELv9SXgvSTDOQ/QEcpXpIs5JmFQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/561bcd4a1b332dc70475a85d77d3c82c/cabd0/main.png","srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/d734b/main.png 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/cabd0/main.png 876w","sizes":"100vw"},"sources":[{"srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/c0126/main.avif 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/42e5c/main.avif 876w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/59596/main.webp 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/d99ef/main.webp 876w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6255707762557078}}}},"excerpt":"요약 Symbol은 primitive type으로 ES6에서 추가되었다. Symbol은 변경 불가능한 원시 값이며, 고유한 ID의 역할을 한다. 객체의 속성(프로퍼티)의 key로 사용된다. Symbol…","fields":{"readingTime":{"text":"14 min read"},"layout":"post","slug":"/javascript/symbol/"}}},{"node":{"frontmatter":{"title":"클로저와 함께 알아보는 curring 함수","date":"2023-02-14","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript의 클로저를 통해 currying 함수를 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAgFBwn/xAAXAQADAQAAAAAAAAAAAAAAAAADBAUG/9oADAMBAAIQAxAAAAFv4K0md1l1IjQceH//xAAcEAEAAQQDAAAAAAAAAAAAAAAGBQECBAcDFyL/2gAIAQEAAQUCV5zt8YF7Awy8V1HMqr98IJksAJQMOeguWvv/xAAhEQADAAICAAcAAAAAAAAAAAABAgMEEgURABMUISIzUf/aAAgBAwEBPwGmZ3jej8mYzDY0bkR9hmVmEisyCFCMKnbf5CoFEcymyrwGA6h6SNKONnd622dj7lm6cDsn8AHj/8QAIREAAwACAQMFAAAAAAAAAAAAAQIDBBEFABIxExQWIiP/2gAIAQIBAT8BXLw5yBrx61g9iYQW7ofx198i+jQs3cFcRE1dCwT0NJr5Zzw0JZvt5AAThCMFjFBoLKSmbETQAKoLE68k+ev/xAAhEAACAgEEAwEBAAAAAAAAAAADBAECBQAGERITFCIjM//aAAgBAQAGPwLMRtlCmF2m2GEobbredwZ1Fhga7jCQInrj0/BYluZqQ5RRb9Y5uKmQ2Olj65tzbLI8PgBYNUnGS8lLmJ7Q6RYlCLltHtlikkMa5O3Wa+XRM7u/OMY/Mv3klkEl1WhpL8RAFrEJfpUgq8xIl5sEVeo+5CQQloNt54mJMw8ljblTqKhaJGmBXCuSRzZT8/ihVZCYUfyJTWMSw2PXQB6K5b+KJsYxmRUOwZlos3aaMY17EKVgxSXmfq08Rqdf/8QAGhABAQEAAwEAAAAAAAAAAAAAAREAMUFRYf/aAAgBAQABPyGMncLZW4pAraiZ78snkTfJtGpmhaK/gJHOt/VfwXFQbiEQgN03jTRRco5gA0Ph5v/aAAwDAQACAAMAAAAQWy//xAAXEQEBAQEAAAAAAAAAAAAAAAABESEA/9oACAEDAQE/ELYYaMhglMI7oOW5DVLUS1OgsAgf/8QAFhEBAQEAAAAAAAAAAAAAAAAAAREA/9oACAECAQE/EF7DFqQ17Ci20BIUGtBO2KiCqv/EABgQAQADAQAAAAAAAAAAAAAAAAEAESFh/9oACAEBAAE/EGwbuUhhs4jmQXnbmsGuGEIEzc3DFfJpe78TiHQDRrFWRM5dEmj2ZEpi6EjQAAADcCqDhk//2Q=="},"images":{"fallback":{"src":"/static/dab08fdc28c522cf2d5cbcd40daae646/a764f/main.jpg","srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/37bba/main.jpg 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/61c72/main.jpg 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/d61e8/main.jpg 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/ba386/main.avif 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/8adb1/main.avif 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/dc6b3/main.avif 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/a66aa/main.webp 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/65dd5/main.webp 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/4fad6/main.webp 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"요약 일급 함수란, 함수를 다른 변수와 동일하게 다루는 것을 말한다. 클로저는 함수와 함수가 선언된 어휘적 환경(Lexical Environment)의 조합이다. Lexical Environment의 Lexical Scope…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/javascript/closure-with-currying/"}}},{"node":{"frontmatter":{"title":"왜 내 z-index는 먹히지 않는가?","date":"2023-02-11","tags":["CSS"],"draft":false,"excerpt":"z-index가 때로 적용이 되지 않는 문제를 해결하기 위해 stacking context에 대해 정확히 알아본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAt0lEQVR42mP4TwFgQBf49w9Efv3y/9GD/4+f/P/7lxTNf/6AyK0b/hqrfQty+vb+9V+4icRoBqleveqWq4bPzjDfc+nXv9wFCvz995coZ4NUvXp34fgK2cPh/FOOGE37tu8OSOLPX4Kagar+gxz5/s+7GXd38pX+Yoj9v+AYSPw3MZpB+v8CTfj75ef/3M1/w5b/O/LgH9jlxGkmM6r+gQP206dPz549e/HixbPnL548fQbkYtUMAEiyAT3z+KCbAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/de2246ea0f89f0544a92309e56a239d4/460e0/main.png","srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/88589/main.png 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/60f9b/main.png 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/914ba/main.png 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/460e0/main.png 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/a6926/main.avif 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/c7a17/main.avif 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/a79a8/main.avif 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/49852/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/79ae4/main.webp 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/06a55/main.webp 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/d2e17/main.webp 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/41672/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.46197916666666666}}}},"excerpt":"요약 z-index는 겹치는 요소의 쌓임 순서를 제어한다 z-index는 position이 static이 아닌 값을 가진 요소에만 영향을 준다 stacking context는 z-index에 영향을 주는 그룹이다 stacking context…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/css/stacking-context/"}}},{"node":{"frontmatter":{"title":"JavaScript에서 배열은 객체다","date":"2023-02-10","tags":["JavaScript"],"draft":false,"excerpt":"배열이 객체인 이유와, 유사 배열 객체와의 차이점을 알아본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcIBv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAZAZ0D6kX4uw/8QAHBAAAgICAwAAAAAAAAAAAAAABQYCBwERAxMX/9oACAEBAAEFAkrjUIq3Wh6sqIzDQItiwgIz3G1dsbEZaSP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAmEAABAwQCAQMFAAAAAAAAAAADAgQFARITFAYRFQcIIhYjMTI2/9oACAEBAAY/AoXeR6LoeayiH+o2PNJScyVdKc5H5IpC49wauqFwhgCv2NdjxMlKK5gca7bfbz11b14/1Gt6tIC3bxd2Wuyh3vzidOuQ93cHGoZVRKeL0aEZMl3cQHJN4UhcVhFoj5fp/GOPhY5ZlSlKiJ3BUxO01q0h4bkriNjWIKjaNGrSNGgFF0dkWpFdK/MRwXdI4qqpySDdhIrJV9Gx7ht/Xu+rv10omzrI3+GPx9mKyhQYrceo8k2VupKyQXfl557WRkyNwhK9IFuI50ApUYauFtwh2CoHRIqHNebCMQqkxiGlP//EABwQAQEAAQUBAAAAAAAAAAAAAAEAESExQVGB8P/aAAgBAQABPyFEIsGhy66qJt36J/g5MyQtpQLQgubCGKY58KA0XVicEMW+nO/UJbl2gVLi1ELNziX/AP/aAAwDAQACAAMAAAAQ8w//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAYEAEBAQEBAAAAAAAAAAAAAAABABEhQf/aAAgBAQABPxCp44fqOPdZujYM2ocIb0HUwqGTYBN8M+Cqmxwuh9LVxprXfojXm8Dz/IG3ixeD46kTRURL/9k="},"images":{"fallback":{"src":"/static/e0c03ecf4f47788bcd911b8d79b30507/bcda9/main.jpg","srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/bcda9/main.jpg 612w","sizes":"100vw"},"sources":[{"srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/90af2/main.avif 612w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/2fed0/main.webp 612w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5637254901960784}}}},"excerpt":"요약 자바스크립트에서 배열은 인덱스를 키로 갖고 있고, length 프로퍼티를 갖는 특수한 객체다. 배열의 prototye…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/javascript/array-is-object/"}}},{"node":{"frontmatter":{"title":"JavaScript의 Getter / Setter","date":"2023-02-09","tags":["JavaScript"],"draft":false,"excerpt":"객체의 접근자 프로퍼티인 Getter와 Setter에 대해 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYEBQf/xAAWAQEBAQAAAAAAAAAAAAAAAAADAQb/2gAMAwEAAhADEAAAAdKtGtYLQxBBKX//xAAdEAABAwUBAAAAAAAAAAAAAAAFAAIEAQMGERQH/9oACAEBAAEFAg0erx1yPpcr0CyQAGA3vSB/M/NZe//EABkRAAIDAQAAAAAAAAAAAAAAAAACERJRAf/aAAgBAwEBPwGUrycLLh//xAAZEQABBQAAAAAAAAAAAAAAAAAAIYGRodH/2gAIAQIBAT8BViL0/8QAJxAAAQMCBAUFAAAAAAAAAAAAAQIDBAARBRIUQRATISIxQ1FhcqH/2gAIAQEABj8CbVb1HvxfDxTKp+GyJbpcmdENRijq72nM48lRUNrpIHzUqLCwAqEhRPPlyWWnmhbKEsaOKjlpH2Kr+VmhlwzDAAAO/XuqNt1L1ybk72SkewFf/8QAHhABAAEEAgMAAAAAAAAAAAAAAREAITFBUWGBkaH/2gAIAQEAAT8h4wD4VOCwuLkvjdcD9NBfyt3AoYmQ9CkPvj3OxTqkPUxCFgGfCkTduUp0q//aAAwDAQACAAMAAAAQKN//xAAdEQACAQQDAAAAAAAAAAAAAAABESExQXHwAGHh/9oACAEDAQE/EESAUsTRWAU+82HHWdr/AP/EAB4RAQEAAAYDAAAAAAAAAAAAAAERACExQVFhodHw/9oACAECAQE/ECFaU6JRk2uL18Ht44z/AP/EAB4QAQEAAgICAwAAAAAAAAAAAAERACFBUTFhgaHh/9oACAEBAAE/EBUm1TsVZ+z4xWBiBBOAq9NDKHnWCAqPTH0TN85+dNI4y4RyB3sQACE2RqJPAQjjj3XjqFqBj//Z"},"images":{"fallback":{"src":"/static/5d3b9180a9db8430e13b85725bd35522/5686d/main.jpg","srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/56262/main.jpg 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/f4b7b/main.jpg 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/16674/main.jpg 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/5686d/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/04d0f/main.avif 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/444d4/main.avif 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/0586b/main.avif 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/d2023/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/2bcfc/main.webp 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/5c9b7/main.webp 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/58a7c/main.webp 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/abb52/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.7140625}}}},"excerpt":"요약 setter…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/javascript/getter-setter/"}}},{"node":{"frontmatter":{"title":"JavaScript의 얕은 복사와 깊은 복사","date":"2023-02-08","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript의 얕은 복사와 깊은 복사로 알아보는 객체의 특성. (feat. React, Vue.js)","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACnUlEQVR42p2Uy09TQRSH/Qd04eMfENwoFumDCqEtlBYaIprWgEIUA7SNTXShCxMTVy6JykJXPlCRBUsiCzBxISISMDxCQS0Jii9CEMpL+qD33s+5t1ioIhpOcnImc85885tzZ+4OtmuKkvTfbMe2QGr4MgU/Vtbm/gOobLJ7GnBiEpZXiC4uEZudS+U2BcqJhJZUJAlFljcHvuxFmQsT7egg3tySXLNRoapIcwFQEd/GxlgOh7XTyGIulVddrV+JoMTiKO1tKE+aYGYmHagtEopUm+h8xsDefQyerSGizqk51VXQ6mqqTvk4ifS2G3l6BOXDxJ8KVYvEYwwXWPi+ew/jO3cx0vSQRDSWhMTjsLSsbZAsjsHUqFDQC/ML6cDGxkbq6uvx19ZStT+DixmZXBAxYLFRe7KCK14/12q9XPb58Xu9nA8E8Pu93Ll6k5bmUUJDX9eB0WgUt9uNyWTCarVhNJpwmfNwlZXhsFg5la3HlV+Aw1ZIqd6I4bAOu8OBUX8Ed2Udn+YVEpK8DozFYlRVVWEwGMjPyyc3O5sivR6nANsNRiw6HQ6zGacplyJRk2s0YBFt0esNnKupQZISqbalFHo8HqHMSEmJE7urFLsaHXaOFlrI0mdjzjdT7Cqh0GbBKdQ5nU5ycnKEkGoSCSkdqFpDQwOnq6upKD9OeeYB3FYrlcfKKRPj0oNZuItLKDukwyPy7hPl+Hw+7VRq7zd+1LSLvSr60Peig/bAGfpbH/N+qIenl3x03b9BsKeNrkfX6eq8xViwew0i//0t/+pD6N1r+vvvMdh3lzevbjMw8IDgcDOhYCuh8ed8nhwRtyeuKZJlSbu/W/4cJKFyMTzHQniahfkZMZ4VcZFIJP7vd74ZcKti7X0r8pbAn9ryNaEySJ7mAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/c0455e771b38f35341c36082f8b7c15c/492b5/main.png","srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/71312/main.png 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/5feb6/main.png 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/492b5/main.png 1160w","sizes":"100vw"},"sources":[{"srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/b57fe/main.avif 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/62df4/main.avif 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/7aee1/main.avif 1160w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/5d2c1/main.webp 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/0bcd6/main.webp 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/9ca95/main.webp 1160w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.789655172413793}}}},"excerpt":"요약 얕은 복사란, 참조형 타입의 값이 바로 아래 단계의 값만 복사하는 방법이다. 깊은 복사란, 참조형 타입 안의 모든 참조가 끊어지는 방법이다. React의 경우 얕은 복사를 통해 state값을 비교하고, 변경 되었다면 리랜더링 한다. Vue…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/shallo-copy-and-deep-copy/"}}},{"node":{"frontmatter":{"title":"nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기","date":"2022-04-10T12:13:47.149Z","tags":["Tool","Node.js"],"draft":false,"excerpt":"NVM을 사용해 프로젝트 별로 Node.js 버전 지정을 자동화 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRtoAAABXRUJQVlA4IM4AAAAwBACdASoUAAgAAAAAJQBdjkAZwBtIGUAeSN/YOv/IoH/w5p6lHd0QTgAA/v//ZyH/66zx//x72KQuDXwT2QKTf+n//27H/yNP9///xPj8F+htBKaI2xLn7VJOy4231//L7+x6//nQeaq/6pm9zGTvi2eFIsIOMc4unw/WW6Ya5c6qf2Fhmnnq5/FdtKP2oZwEj/9vf+9Z/2HRLOBl8///w8/irP1GbK8l4BudWc8HcamhbFwmnr5597nw534+O8mwMHmNv324Jg7PcoAAAA=="},"images":{"fallback":{"src":"/static/c7934c26406e2c570808f63f8ceaa552/7592a/main.webp","srcSet":"/static/c7934c26406e2c570808f63f8ceaa552/1e0c8/main.webp 750w,\n/static/c7934c26406e2c570808f63f8ceaa552/7592a/main.webp 1000w","sizes":"100vw"},"sources":[{"srcSet":"/static/c7934c26406e2c570808f63f8ceaa552/7c2eb/main.avif 750w,\n/static/c7934c26406e2c570808f63f8ceaa552/588e1/main.avif 1000w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.42}}}},"excerpt":"nvm이란, Node Version Manager로, Node.js의 버전을 관리하는 도구다. 시스템에 여러 개의 Node.js를 설치하고 사용할 버전을 쉽게 전환할 수 있도록 도와주는 유틸이다. 이는 쉘(sh, dash, ksh, zsh, bash…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/node/setting-npm-differently-for-each-project/"}}},{"node":{"frontmatter":{"title":"PDF 페이지 CSS로 안전하게 작성하기","date":"2022-04-02T12:13:47.149Z","tags":["CSS","HTML","PDF"],"draft":false,"excerpt":"웹을 개발하다 보면, PDF로 문서를 사용자에게 제공하는 기능을 구현해야 할 때가 있다. 다른 개발자분들이 헤매지 않을 수 있도록 정리해보았다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKklEQVR42pWT0U7CMBSGu3nFg+iNS9DoAxB9ARIeghm9dO+i0QteQLxAJJAt8CgwE2AjoHZAu0Dy2xYDi+vidvHnpKfnfGn/0xLOObRiDHyzQQyktd3u9jV9JBMmmlgQgPZ6oN3uQWIt8zwDSrJOJpvG5TJGhMA3TPjEUFGux2fnO6io+wtNA9drda3I8zAUzSPDUJC9TFPlo/5A1fHV6h+gKJCF360WJqcWFrd3CK+u8eU4mF5cYmHbmByfgHY6BYEvTcxqNTDXxfLpGZ/3DqKHR7C3NqaWBdp+LwhsvmJWrSpoUKlg2Whgbt9gXq8LPwmo6+UE/npIEx76Qh+lkvDv6ODhIK+HminvByPisPCUk+8wDMU0+ynJfP53mITGsfanyLy0RvdTfgD4wgAkBeu5twAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/39ee9e2452b5c68830fa2ebb9eec0967/b5380/main.png","srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/5b584/main.png 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/c1f05/main.png 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/b5380/main.png 1200w","sizes":"100vw"},"sources":[{"srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/4814e/main.avif 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/acf79/main.avif 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/30577/main.avif 1200w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/73e0d/main.webp 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/9fede/main.webp 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/81547/main.webp 1200w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"웹을 개발하다 보면, PDF…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/html/securely-create-a-pdf-page-with-css/"}}},{"node":{"frontmatter":{"title":"Tripllo 삭제 및 일상 회고","date":"2021-12-04T15:13:47.149Z","tags":["Tripllo 제작기","Diary"],"draft":false,"excerpt":"정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif 파일도 모두 백업해두었다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABmElEQVR42p2T607CQBCFff8n8Qn8I2qMxgtaFLGUdun2Lrbd0gu1RQocp0skxMQITnLS2d3p156Z7BF2Yr0CnuwBLgd9XD8bJB0K89EjPYycre41Gy9mgOVqhZ9xtLtoz0+UK1z0+9B0Do1xDA0Ttj9BXtYoygpBnOH0cYTboYVm+SdwjTvVhaL7+JzXmNc16qqifL6tKao5OoqO+6G9H/BG5dJW+P4Oz/MQhiHtN5uWJMfIomucPXsE5PsCLQmcTqcSlqYpFovFpqDWkWc2Oj2TgNZhwKZpUJYlJhPqX57L9T8tb4B1XUEIAcMw4Lou/CCgD8xoOBXOegf28FF3wRiD7/sSGkWRtC/iGGlREtA4HGjoOlRVBecclmWBjcdwbBtJPpPAu0Mst0BNG0JRFJimKeU4DiyCT+IEF0+MgHsO5Vb20JV9a8W5JZ+MjSW4tXxOwP0sr9fojjy6asF2L00z+jsXdCRjRlNugV1y8dvVE99aLleiZ7hSSVEKkZUiTDLxFiUipjwpPiifik53ILqvpqzffb/VF0Se2AeYKr/nAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/688b437d9037a2279635c487fefa0aad/a030c/delete1.png","srcSet":"/static/688b437d9037a2279635c487fefa0aad/d734b/delete1.png 750w,\n/static/688b437d9037a2279635c487fefa0aad/a030c/delete1.png 877w","sizes":"100vw"},"sources":[{"srcSet":"/static/688b437d9037a2279635c487fefa0aad/c0126/delete1.avif 750w,\n/static/688b437d9037a2279635c487fefa0aad/fd774/delete1.avif 877w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/688b437d9037a2279635c487fefa0aad/59596/delete1.webp 750w,\n/static/688b437d9037a2279635c487fefa0aad/8026f/delete1.webp 877w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6259977194982896}}}},"excerpt":"3주 전에, 정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/tripllo/tripllo-delete/"}}},{"node":{"frontmatter":{"title":"vue-meta와 Meta tag","date":"2021-05-30T20:13:47.149Z","tags":["Vue.js","HTML","SEO"],"draft":false,"excerpt":"Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYCBQn/xAAVAQEBAAAAAAAAAAAAAAAAAAACA//aAAwDAQACEAMQAAAB34VL1eUnMiGv/8QAHBAAAgICAwAAAAAAAAAAAAAAAgMBBAASBRMx/9oACAEBAAEFAiHYeORaBmWZnRK+pkef/8QAGxEBAAEFAQAAAAAAAAAAAAAAAQIQIUFRkaH/2gAIAQMBAT8BkDIde5ONyn//xAAYEQEAAwEAAAAAAAAAAAAAAAABEBFxwf/aAAgBAgEBPwELN5H/xAAhEAACAQQCAwEBAAAAAAAAAAABAgMABBEhEjETMlFBYv/aAAgBAQAGPwJl2OQIyDgjPwjYqZrl7giNvFCJZOSsnfkADnPfs+X/AK1haKg4DqwJBZXGu0dWUqfhGx+UJFluWYRYxNd3U0Z12YpJShfXvjlQr//EABsQAQEAAwADAAAAAAAAAAAAAAERACExEFGR/9oACAEBAAE/ISZQqqZKgQ6IjiCsSYLArSJIQU+MNAB1DEE9eoihM4ybUtOJg3BsduKp7B+mf//aAAwDAQACAAMAAAAQDM//xAAaEQEBAAIDAAAAAAAAAAAAAAARAQAhMUFh/9oACAEDAQE/EL3Usl0bFnbz0XWc5//EABoRAAICAwAAAAAAAAAAAAAAAAERITEQUWH/2gAIAQIBAT8QORKijYG2FPCxj//EABoQAQEAAgMAAAAAAAAAAAAAAAERAEEQIWH/2gAIAQEAAT8QZjABCO8nBCEcMrCgOhRQ11R4G4JRRwO6L3coMOi14aBpEtYhrMyrSygsqs72r7n/2Q=="},"images":{"fallback":{"src":"/static/41787407cbf03fd6193412aa3138ab5a/ce8f8/main.jpg","srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/ce8f8/main.jpg 613w","sizes":"100vw"},"sources":[{"srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/289cb/main.avif 613w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/4bf02/main.webp 613w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6394779771615008}}}},"excerpt":"Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자. Meta tag? 서비스 기획 -> UI, UX 상세 설계 -> GUI…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/tripllo/(2)mysql-design-spring-boot/"}}},{"node":{"frontmatter":{"title":"(1) 제작동기","date":"2021-02-03T10:03:47.149Z","tags":["Tripllo 제작기"],"draft":false,"excerpt":"Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/4 정도 만들어진 상태로 배포되어 있다. 어플을 만들면서 다음번에 같은 문제를 만났을 때 참고할 만한 자료를 남겨두어야지 생각만 하다가 지금부터라도 남겨두어야겠다 싶어 제작기를 적으려고 한다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACHklEQVR42o2TPWzTUBSFOyHEyIBEBzbEjxgoEiCEkFDF3AkWBGJHCLFVgg11QiITAwszKwOwdGkFaoS6lKJCfyAkKY6dhDT2s/3+ncN9L2lhIbGl4yfbz5/Pvfd4iuUc260A9UaIH902lDJQxiLq7GGnFiCklQuNNJcQUkNpO1ZThR2gsvwGVx4/xIdgEzDwQAcIot9IMw6W5oiTDFIqWDMBaKRFjXXwfO0tjC2Qc+XXJOWoketUWC/mxA3iXEOoMcAsF75MrQ2EUFTeEMgIuLHVwGazizZTiBKJdqIQxhK5dPv/AxRUhnOlZIGMC0jXw9FDB2Ush6UPeJnhOrZkpTS4zhCxJjkzvvGaXvwVdvFtu4FuL/HXbrMcaQLQ4P3WK7yoPsJ6+BEFDUVS+W6yzaCDrwRttffQd0P5x/1Y4Ov1Z1hYuoNq8x1gQU3/28fvPwMkjJPLAQFtOWAvi/AlXIHQnKIxdOHKTDywhZAcuj5rUwZIJ1sUcMf+Cw6W0vR3yF3U7VMWBXiJUHugi0nMMlJKjnLfJxeJnO67Ut1Ui2LgW1AKOP+0gmNnr+HEzA2vldXP3m1jt005rKPXT71iik8p4N378zh68hKuz93GoelzWFyqeqADuNh0ejEy+g2dSgHvPXiCI9OncOHyRRw+fhqLy5880A2kvhuNyh4cZHEicKHyEmeuzuH87C3MzN7E6trGgcNW1PM9lSVA+8A/pUlh2d91KpcAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e4152/main.png","srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/17a2a/main.png 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/55283/main.png 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e4152/main.png 1107w","sizes":"100vw"},"sources":[{"srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/676a5/main.avif 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e198f/main.avif 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e7002/main.avif 1107w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/3c28e/main.webp 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/d475f/main.webp 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/b6a06/main.webp 1107w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.7262872628726287}}}},"excerpt":"Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/tripllo/(1)production-motive/"}}},{"node":{"frontmatter":{"title":"오라클 CHR, ASCII 함수 사용법","date":"2020-06-12","tags":["Oracle"],"draft":false,"excerpt":"CHR(), ASCII() 함수 사용법.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"정의 : 아스키코드값 얻기(숫자) : CHR값 얻기(문자) 이렇게만 적어놓으면 뭐가뭔지 잘 모를테니, 문자로 아스키코드값과 아스키코드로 문자열 값을 얻는 쿼리문을 한번 보자. 결과는, ASCII(‘A’) ASCII(‘Z’) ASCII(‘a…","fields":{"readingTime":{"text":"2 min read"},"layout":"post","slug":"/oracle/CHR-ASCII/"}}},{"node":{"frontmatter":{"title":"오라클 테이블 스페이스 조작","date":"2020-06-11","tags":["Oracle"],"draft":false,"excerpt":"Local Oracle 사용시 용량에 문제가 생기면 이 방법을 사용하자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"이동욱님이 쓰신 책을 다 떼고, SQL을 공부하기 위해 DBlan에서 나온 SQL BOOSTER라는 책을 샀다. 쿼리문을 잘 다루는 백엔드 개발자가 되기 위해 SQL…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/oracle/table-space/"}}},{"node":{"frontmatter":{"title":"ORACLE 계정관련 명령어","date":"2020-06-10","tags":["Oracle"],"draft":false,"excerpt":"ORACLE 계정관련 명령어로 테이블 조작을 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"표시가 붙은 녀석들은 SQL PLUS에서 사용하는 명령어가 아니라 그냥 CMD 창에서 치는 명령어들이다. 데이터를 이관할 때, ORACLE 계정을 새로 만들어야 할 때, 유용하게 사용되는 명령어들이다. 1. 계정삭제 혹은 후에 2. 계정생성…","fields":{"readingTime":{"text":"1 min read"},"layout":"post","slug":"/oracle/계정관련-명령어/"}}},{"node":{"frontmatter":{"title":"Spring에서의 MediaType","date":"2020-05-27","tags":["SpringBoot","MediaType"],"draft":false,"excerpt":"Spring MVC에서 MediaType 매핑에 대해서 알아보고 테스트 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVR42m1T32vTUBROO4dOUfDNMQWfRFQULIzhltwk3cAHn4S+CNKhWHW5SbOkFXyQO6YTUUGrBadOEEWQgmhy0x/bukYFwYfBQNA96F+ggogPsqf4JVmdWi8cTnLu+fGdc74rCPFJCJ0n8bcOYh3E/7nFXHemkumKTKEttifWgpmQZAFLRk5rDsJ4ZaAndzfVzRhL2rMjm9oBhqekzLrYG8ZE4pN1OTe1MbrUXPGgzqUl6pL30Mu6K73Va2T76cpAH3WlW4YrHdM9MqVxMmF40pjOybTukgJkCvabRpWcoaHdJdejhOasMgf5jotGvkqa+F7J15WHuWdiL+VIyEkZcsl6nd5lL6hLVlPVIKMFP92ym+qeQivtIOYKAO0WUOG42VC+AQlD5ZLuybc1T5qE7YfB5azmiCYKTZt18hT3ExCTVuVB6pFhdHN1nKt91JFPUkcqU05eCoUF1YfTh6KfLqP6su2nP6H6ZSD9Cv0ommMTQVwS/1zK6gJ+LwEJjyLPecGoyVm0F2jPRVNzpXkgrqC9C/m6vIJZWkBunPWGto55ZJvpKHuxtB7DGdpP+eCBEO0/ReJjzikta179SR3xAeRJ0R8O0PKM/WZkn91SHYzhnuHJ9/VqNJI71JVvIGam+EottWmTqQhdLBCSMVwu9mMeH7HNz9BfUPmd1RB35OtkJ1A+Nrh0DgMv4nsSczqF9q9hhqPwvajX+rf8D2UHsYMgJnLWJxsiHoJnbPFIxLMTLw5tDhPopcPrQw52PIk2OduEDsnNWAw/bCdsJWqJCavEDxKhfxB0vrBf2Ion9AeQW1wAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png","srcSet":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/8315cb308b890c7087edfc088043f572/1260c/springboot.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/8315cb308b890c7087edfc088043f572/22c65/springboot.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"계속 JUnit에 대해서 공부하고 있는데 속성으로 MediaType이 등장했다. 궁금증이 생겨 MediaType에 대해서 조금 알아보았다. MediaType이란? wiki의 말에 따르면, 미디어타입(media type…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/spring/MediaType/"}}},{"node":{"frontmatter":{"title":"JUnit(2) - Mockito","date":"2020-05-25","tags":["SpringBoot","JUnit"],"draft":false,"excerpt":"Mockito 프레임워크를 통해 Mock 테스트를 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMABhqAAAYagAH+TSlKAAAByElEQVR42mNgoBwwUsUA12IlsehG44qClmhJbm4lMaAQK1mG1dfXM4EY8Y22fbtPrv//7Mmrk9NmLDowbdEiMbwu+P+fgRGEQWyYISCwatUqZhA9Y8XcxE9fv/6/cev+/5Nnr//6//+/NtyE+np7lspVNqIVC52F6+fbc4DY9avseUC4ZqGdZu0SB+vQUBlOVlZWIw4ODnuQntLu1Ky+jaX/p2zu+Hf46sFvrz5+VIUbWLvU0bh6sV1V1SL7yurFtvHVi2yjqxbZJlQvtEmtX2pt07TaaWZKo4E/UGk+CxtLMZD29Ylz7y+Ylvi/cGLs/8M3tz8FupAXYeACR+PahQ72NUvsfeqW2MdWL3LMrFlsn1K9yCG7ep6rU/0Kh7L4WsNgoNIwLi72RCAdY+/qWrnt1MG/Dz+/+f/w7btVkGD6D4nxiYvr+aYtrRCctqhebNrSaYKdM9JMeuZVy7bNLlRpmRVvMGH2BPGOCXlyubkpMlFRiUoeHn5art7eOvfffiy+/ertgvP3nxhADYSENchkGN6//z8LSOLMmTOsIAySP7bjmNC2bdvYgeJs+/fv5wgNDWUGspnhLiIlsSJpQqbBGBTj6AYDAGU710j0CbAkAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/494e2ef858fa149461fcb71d317a1049/ed3fb/mockito.png","srcSet":"/static/494e2ef858fa149461fcb71d317a1049/e7dcc/mockito.png 750w,\n/static/494e2ef858fa149461fcb71d317a1049/ed3fb/mockito.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/494e2ef858fa149461fcb71d317a1049/06049/mockito.avif 750w,\n/static/494e2ef858fa149461fcb71d317a1049/c1b27/mockito.avif 800w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/494e2ef858fa149461fcb71d317a1049/ee7ce/mockito.webp 750w,\n/static/494e2ef858fa149461fcb71d317a1049/e7773/mockito.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5}}}},"excerpt":"이전 포스팅에서는 Assertion 객체를 사용해, 테스트 코드의 return 값을 검증했다. 단순히 return 되는 값만 검증한 것인데, 만약 return 값이 없는 테스트를 하려면 어떻게 해야할까? 즉, void…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/spring/JUnit(2)Mockito/"}}},{"node":{"frontmatter":{"title":"Github Blog에 카카오톡 공유버튼 만들기","date":"2020-05-22T09:03:47.149Z","tags":["Blog"],"draft":false,"excerpt":"Jekyll로 만든 Github 블로그에 카톡 공유버튼을 만들어보자!","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACjUlEQVR42n2S3UtTYRzHDxSs/yDDCV103V1BFERE0UUXvQgW5oV0MRsJLXyBkWggERZh4KKEglw4pEZYbIgGw+VrKnO+bZ6lObez7WznOWfbOWda23m+PZuQXURf+PCF38PzuXieH2dtaalqa3tsttvs1RaLpdpms/3Bbi+3hbX9v3R2dpqtVmsVx3EHuNji8qwSC2gR8j2Ty+WJLMtEVhRSTjpNiEgKRMxkiJhKEVEU/0WGRY9Go9+Y8BAnSySyvb2FpdCqMbcQQCjMg+d5rEe2UMjHUODfoqRkUA6lFLTc2I/BUm5d19eZ0MSl06lIeG0VK8GAMTczBT4cwvJSEMGVMPTNaejDtTDkxN5tauDvlMWlfWG4IsxreiTPBnEdRmKHQi0COe0nNuMy1rdkRBM7UPRfWEvnMR9XEEhkkVR3gaIIWtyEUdpgQgm6lt0Tzv7IRRo8Om5/loy6DxK6vqpo7/mEs7deor51EOfrX6DbPQ+uw4OTDj8OPvCgdnAeSDcjvXAa/Pg5A6kr0MgsE14ycf4Nhb/2UUP/Qq5k9crU9iVL73S8p3X33tFXQ9P01NVe2jowSbn2YfpwZJnWPBqlF/onKUgjHRs8QZ90nSlBvAg17Q9x3HMTtyiokdYJ4O6YbjR6dTiCRTx9PY7LTQO42TKEhvsuOEbXcLR3AscdUzjcM45mTwjIdqEUuw4jecNAvgm6EmCfcszESZI8kcntZJKKFksoqqCoBUFW8kI8KQlCkggJkQg5VRO2paywKSoVpJwq7BaIUFAFQcsnYrs62y8i+Stv2NfXVzXictX43E5zGbeTwXrG563gYzjZbMbrNvM+tznI2svO+51uhq/CG9dITXf3syPlxf4NkN9Kkm8uxCEAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/122e747ed0f9d7367c71f42c3f5a94fa/81543/main.png","srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/81543/main.png 605w","sizes":"100vw"},"sources":[{"srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/5f09e/main.avif 605w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/5fc57/main.webp 605w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.48099173553719005}}}},"excerpt":"개발 공부를 하다 공부한 것을 OneNote에 기록해두었는데, 항상 구글링 할때마다 개발자들이 github.io 로 된 블로그에서 도움을 많이 얻어 나도 언젠간 공부한 것들을 내 github 블로그에 포스팅 해야지 싶어서 github…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/blog/jekyll-kakao-share-button/"}}},{"node":{"frontmatter":{"title":"JUnit(1) - 개념","date":"2020-05-21","tags":["SpringBoot","JUnit"],"draft":false,"excerpt":"SpringBoot에서 JUnit의 개념짚기.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVR42m1T32vTUBROO4dOUfDNMQWfRFQULIzhltwk3cAHn4S+CNKhWHW5SbOkFXyQO6YTUUGrBadOEEWQgmhy0x/bukYFwYfBQNA96F+ggogPsqf4JVmdWi8cTnLu+fGdc74rCPFJCJ0n8bcOYh3E/7nFXHemkumKTKEttifWgpmQZAFLRk5rDsJ4ZaAndzfVzRhL2rMjm9oBhqekzLrYG8ZE4pN1OTe1MbrUXPGgzqUl6pL30Mu6K73Va2T76cpAH3WlW4YrHdM9MqVxMmF40pjOybTukgJkCvabRpWcoaHdJdejhOasMgf5jotGvkqa+F7J15WHuWdiL+VIyEkZcsl6nd5lL6hLVlPVIKMFP92ym+qeQivtIOYKAO0WUOG42VC+AQlD5ZLuybc1T5qE7YfB5azmiCYKTZt18hT3ExCTVuVB6pFhdHN1nKt91JFPUkcqU05eCoUF1YfTh6KfLqP6su2nP6H6ZSD9Cv0ommMTQVwS/1zK6gJ+LwEJjyLPecGoyVm0F2jPRVNzpXkgrqC9C/m6vIJZWkBunPWGto55ZJvpKHuxtB7DGdpP+eCBEO0/ReJjzikta179SR3xAeRJ0R8O0PKM/WZkn91SHYzhnuHJ9/VqNJI71JVvIGam+EottWmTqQhdLBCSMVwu9mMeH7HNz9BfUPmd1RB35OtkJ1A+Nrh0DgMv4nsSczqF9q9hhqPwvajX+rf8D2UHsYMgJnLWJxsiHoJnbPFIxLMTLw5tDhPopcPrQw52PIk2OduEDsnNWAw/bCdsJWqJCavEDxKhfxB0vrBf2Ion9AeQW1wAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png","srcSet":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/8315cb308b890c7087edfc088043f572/1260c/springboot.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/8315cb308b890c7087edfc088043f572/22c65/springboot.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"Web 프로젝트를 하다보면 오류는 당연히 만나는 것이고 그 때마다 을 찍어보거나 로 log를 찍는일이 대부분이었다. 또 log를 확인하기 위해 WAS를 올렸다 내렸다하는 번거로움까지. 하지만 WAS…","fields":{"readingTime":{"text":"4 min read"},"layout":"post","slug":"/spring/JUnit(1)motive/"}}},{"node":{"frontmatter":{"title":"Java 다형적 변수, 형변환","date":"2019-07-19","tags":["Java"],"draft":false,"excerpt":"Java의 다형성을 통해 다형적 변수와 형변환에 대해서 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUGBwn/xAAWAQEBAQAAAAAAAAAAAAAAAAAGAgP/2gAMAwEAAhADEAAAAd7ou9V5WrKZDir/xAAaEAADAQEBAQAAAAAAAAAAAAAAAgQFAxIV/9oACAEBAAEFAlJb07H01Y9C58vM2L6pND//xAAgEQACAQQCAwEAAAAAAAAAAAABAgMEERIhEyIABkEy/9oACAEDAQE/ARbB+9mOICcKvkL3J5TIGiIsPyj5gkEr9p/UqipghnSpGM0aSLpR1cBhptjR+78//8QAHxEAAgICAgMBAAAAAAAAAAAAAQIDERMhBBIABkEi/9oACAECAQE/AW7ZEpLUdiXzMnU1QGERsswNnbOmMgEBr1P7RDx5pYG436ido2ssdoaO1NfPmvP/xAAoEAACAAUCBQQDAAAAAAAAAAABAgMREhMhAAQiMTJBUVJxgZGhsfD/2gAIAQEABj8Cn+fb41ujHYIq7hxCnKGbahKVUVFopMme4k0cZEukEptNwYc+B4liFcX1osSMHoJmAWVCSDwykTSe/D46g38P3qAqLFEmNDncRmdDQchndsnvy+saj7e5ctkCvpqmA2RnOZHzzkOWv//EABsQAQEBAAIDAAAAAAAAAAAAAAERIQBRMUFh/9oACAEBAAE/IZFWk7drnx3XJc4JPRwNTWtRGO8LV16foeaNPDOIpyElpojU6Awefa+U8pJ9Rl+PWDirvaoWBEUgCgxCBY//2gAMAwEAAgADAAAAEPwv/8QAGREBAAIDAAAAAAAAAAAAAAAAAREhAEFh/9oACAEDAQE/EGZEiAQw7LgAj8BwxQ9B1IA5FG7L/8QAGBEBAQEBAQAAAAAAAAAAAAAAAREhAEH/2gAIAQIBAT8QDiDtZa4ho131HJEhxa21Oq32yZP/xAAaEAEBAQEBAQEAAAAAAAAAAAABEQAhMUFR/9oACAEBAAE/ECyUSweRtASj1AFdZobnXPFOnx0mF95UIThfBEQ8r9idS3uL8EpfwcxdO3GlIcRMkW1HNKYZk64M9Dv/2Q=="},"images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/2a117/java.avif 396w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"…","fields":{"readingTime":{"text":"2 min read"},"layout":"post","slug":"/java/다형적변수/"}}}]}},"pageContext":{"limit":1000,"skip":0,"numPages":1,"currentPage":1}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file +{"componentChunkName":"component---src-templates-index-tsx","path":"/","result":{"data":{"header":{"childImageSharp":{"gatsbyImageData":{"layout":"fixed","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAcDBgj/xAAVAQEBAAAAAAAAAAAAAAAAAAAGBf/aAAwDAQACEAMQAAABzQva40ELOEcQkgf/xAAbEAACAwADAAAAAAAAAAAAAAADBAECBQAGE//aAAgBAQABBQL0UyFDdpd1bL5LRxo5FNGQhpXi9IEH/8QAHREAAgICAwEAAAAAAAAAAAAAAQIDERIhAAQFBv/aAAgBAwEBPwH2PXm9TrJGsaQdaXaAWzuq6yZqGssmUVGbJDKRR4Pk+kQDIXzIBaiKyOzXP//EACARAAICAAYDAAAAAAAAAAAAAAECAxEABRIhIkEVMUL/2gAIAQIBAT8ByWSFZ3eUmaaMnUxHBS4U0i98QoJbUK9BSWx5JvlqXoVVDathsMf/xAAoEAACAQIEBQQDAAAAAAAAAAABAgMRIQAEEyIFEhQyUTFCUmFicrH/2gAIAQEABj8C5s1MkOygBI5z8iF9f4MDL8Gyr9PHbqpdsQN95c7a/SCRgMak+cleUncYlTkraw1Q7mnk0/UYjzvFZ5M+8i6qwtWPLJc20gzGTt97kfjW5CqAirZVUBVUWsFFhiNVr2hvFS1zj//EABsQAQEAAwEBAQAAAAAAAAAAAAERACExQXGR/9oACAEBAAE/IeHYbkNi8yxRF75noeMJgQF66ZGii5b3IQEK4ipYvg4MCvkguFPTw7g4HB1Hmgiga4HPxTgWIsKjHtZ8A4Gf/9oADAMBAAIAAwAAABB4/wD/xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMbH/2gAIAQMBAT8QJVgsOFuOoA4zyJbmWQETgqedJ//EABkRAQEBAAMAAAAAAAAAAAAAAAERIQAxUf/aAAgBAgEBPxCsLwy2CtDrY4hxVVLZS6QAALgAST3/xAAYEAEBAQEBAAAAAAAAAAAAAAABEQAhMf/aAAgBAQABPxBcTSzYF+gAcsIXKKklBqBnqI/NngCtchQV+CQiLzIgTRYqyGWJj8AMD5nDzB2B9mKjKoIFkKgWpbgP/9k="},"images":{"fallback":{"src":"/static/9fcf46c14997dbd0a642e9bf12069a20/de8d1/back5.jpg","srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/de8d1/back5.jpg 1920w","sizes":"1920px"},"sources":[{"srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/797d7/back5.avif 1920w","type":"image/avif","sizes":"1920px"},{"srcSet":"/static/9fcf46c14997dbd0a642e9bf12069a20/d85eb/back5.webp 1920w","type":"image/webp","sizes":"1920px"}]},"width":2000,"height":1333}}},"allMarkdownRemark":{"edges":[{"node":{"frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","date":"2024-02-04","tags":["Bundler","Vite","Environment"],"draft":false,"excerpt":"Vite의 철학에 기반한 방식 import.meta에 대한 이야기","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/ba386/main.avif 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/8adb1/main.avif 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/dc6b3/main.avif 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"frontmatter":{"title":"모던 CSS 적용 방법 둘러보기(CSS-in-JS with zero-runtime)","date":"2023-10-08","tags":["CSS","Performance"],"draft":false,"excerpt":"전처리기부터 Atomic CSS 까지, 웹 어플리케이션 개발에 필요한 CSS 적용 방법 및 최적화에 관한 이야기","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcICf/EABYBAQEBAAAAAAAAAAAAAAAAAAcFBv/aAAwDAQACEAMQAAABzEbqqcjgEzGUiQ81/8QAGxAAAgMAAwAAAAAAAAAAAAAAAwQBAgUABhL/2gAIAQEAAQUCxknXz9owKIt3G7M4qg+Ux0byVQPv/8QAIBEAAgICAQUBAAAAAAAAAAAAAQMCBAURBgASExRBFf/aAAgBAwEBPwG7zfA4q1mq17CLs17SV/k+CrX9jHXFrmJFtizKc7FWw6QmyCvVmpY8aj36cI80UYgjHpAI2BonQ+Df3XX/xAAeEQACAQQDAQAAAAAAAAAAAAABAgMABBESBQcT0v/aAAgBAgEBPwGXsqOBbbI5L3gkk9ljuFFvdwyLgKQVzA8R1ZH1udmU5ARylHs7kSc/Vf/EACQQAAICAQQBBAMAAAAAAAAAAAECAwQRAAUSITETInGBIzKR/9oACAEBAAY/AvSqSQGNVRpnss4WBGfgH/GGlcA5J4KcAd4yud5bZDfu7FtNmnSfdrZpx5t3IJLMUMccEhEqmsi2OQGYlkCWMPxL5HuB7Vs+QfB+9IcsGHhlZkYZ84ZGDD6PevVkjaWQjszSzS5+VeQqfgrjX6j+a//EABsQAQADAAMBAAAAAAAAAAAAAAEAESExQWGx/9oACAEBAAE/IaMOOpmZAB69oRT4BXgPmEc0tR9GAVbgzgUktD4w6aydgHYYuzq14YFmi0KixqEQABQUoCzPPk//2gAMAwEAAgADAAAAEMf/AP/EABcRAQEBAQAAAAAAAAAAAAAAAAERIQD/2gAIAQMBAT8QYd7v3iIPcXvQl/FoXUCUGLCpYXP/xAAaEQEBAAIDAAAAAAAAAAAAAAABESFRADFB/9oACAECAQE/EGRoZHE3Y+FAzoIlbLhUZca7hvzn/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAMUFh/9oACAEBAAE/EJsiZVLs8ZmdBLO3H/FAjzDjRSuUq/7vxJ3qkLHEcQSkA1AEAyvkA0MofXmFwxmYANAAEAAAAAgAAb//2Q=="},"images":{"fallback":{"src":"/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg","srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/6cce3/main.jpg 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/dec99/main.jpg 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/12c41/main.jpg 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/2e6cc/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/b56ea/main.avif 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/72ed6/main.avif 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/aa501/main.avif 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/c90a0/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/01d11114d30ea9cb1f8571db9fad39ab/d2a19/main.webp 750w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/39bea/main.webp 1080w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/8f28c/main.webp 1366w,\n/static/01d11114d30ea9cb1f8571db9fad39ab/237ec/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6682291666666667}}}},"excerpt":"모던 웹 개발 생태계에서 CSS를 제작할 수 있는 다양한 방법이 있다. JavaScript 웹 프레임워크 분야는 거의 React가 대부분을 차지하고 있다. CSS 프레임워크(혹은 라이브러리)도 React의 영향 때문인지, 프로덕션에 CSS-in-JS…","fields":{"readingTime":{"text":"29 min read"},"layout":"post","slug":"/css/explore-how-to-apply-modern-css/"}}},{"node":{"frontmatter":{"title":"ESLint로 import 구문에 규칙 넣기","date":"2023-09-06","tags":["Environment","ESLint"],"draft":false,"excerpt":"규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUGBAj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAgJ/9oADAMBAAIQAxAAAAHvHe+f5P0/BF+Ih//EABoQAQACAwEAAAAAAAAAAAAAAAMCBQABBBL/2gAIAQEAAQUC6GPkWPhM3zri0xvYTrybRVxDH//EAB8RAAICAQQDAAAAAAAAAAAAAAECAwQSAAURFDJBgf/aAAgBAwEBPwG1utZUqNXnLStXJurJE+C2ezPikRwU4dUVizEvzKX4I8QN/X2V+I/Gv//EACERAAICAQQCAwAAAAAAAAAAAAECAwQRAAUGEhMxISJS/9oACAECAQE/AavEdulijhsVN0SbBLXK12jIFYscI1KfxiXqvUhktwDBwQxBOpuEW0ldYPJLCGIjkeWtEzp8YZo/v0JHte7Y/R96/8QAKRAAAgECAwUJAAAAAAAAAAAAAQIDERIABEETMTJRkQUhIiNCU2KBkv/aAAgBAQAGPwLKwy7Ta513SBI0vLGNb3J5KBriiSLf7beCT8Pa3QHHCcZPtBp5LsnFPFHFapj8/ikPqvA7hQ7sUlo4+SKeld31ixXkpWouYtSuguqQvIVoNMf/xAAfEAEAAgIBBQEAAAAAAAAAAAABESEAYVExQXGBseH/2gAIAQEAAT8hOZJ8EwBJsnuWCWkJMbB+tY0N3gl+H7l5NnRrIoCaClVkpuNG7UlcKE5ydvOXQa9keUMArP/aAAwDAQACAAMAAAAQMC//xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMWH/2gAIAQMBAT8Q4O0KU9CJGmAMBgUAWqtWKDO7QfNF/8QAFxEBAQEBAAAAAAAAAAAAAAAAAREhUf/aAAgBAgEBPxBYdg6WI/aaU4gf8yz1NIiqAxf/xAAZEAEBAQEBAQAAAAAAAAAAAAABESExAKH/2gAIAQEAAT8Q0HMw9uc8VKcfFzB1TDpsLF4sQFMk23dfQ95nPAkThPFrXyLQQletTC1yUzDoTQO+UZGmJV7sU1EQB//Z"},"images":{"fallback":{"src":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg","srcSet":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/745053477406742b937cf317c03bd51c/2afe8/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/745053477406742b937cf317c03bd51c/62859/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671874999999999}}}},"excerpt":"프로젝트를 진행하다 보면 하나의 파일에 import 대상이 많아질 때가 있다. import 문이 많으면 어떤 모듈이 import 되었는지 파악하기가 쉽지 않고 지저분해 보인다. 위의 이미지는 Next.js 프로젝트의 파일의 import…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/environment/putting-rules-into-import-syntax-with-eslint/"}}},{"node":{"frontmatter":{"title":"GitHub Actions 캐시 조금 더 다뤄보기 (feat. restore-keys)","date":"2023-08-22","tags":["DevOps","GitHub Actions","Automation"],"draft":false,"excerpt":"restore-keys는 기존 캐시가 쓸모없어졌음에도 불구하고 기존 캐시를 불러오는 기능이다. 그렇다면, 무효화 되지 않은 캐시를 어디에 사용해야 하는 것일까?","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRtoAAABXRUJQVlA4IM4AAADQAgCdASoUAAoAAAAAJYgCdL1CScCMIDOJauZFWWvwAP7+fCRqJ1HSVO9tIR999fXyP/P57rC8REMKD1//0ioeS1//ZcuF7B+ofR9C21V2uWjaFEHZ/V9j/+YjqrWQX/oM//3/Xef38974//DpwZKlrsnStauDGxKwCIg6sCCzNEAE1v/+tZbF+e3c/dp8J2s0//xoH+/2b/MdD0ufroUYn//1ag//2gH//Wsf0DSlimwf/X6RG3r/0P/tmbftAf4hf79ZmYcMFl0JnQAAAA=="},"images":{"fallback":{"src":"/static/365cb7658cd8164573e7796d96f879bc/34dc0/main.webp","srcSet":"/static/365cb7658cd8164573e7796d96f879bc/3fe34/main.webp 750w,\n/static/365cb7658cd8164573e7796d96f879bc/da172/main.webp 1080w,\n/static/365cb7658cd8164573e7796d96f879bc/b3e28/main.webp 1366w,\n/static/365cb7658cd8164573e7796d96f879bc/34dc0/main.webp 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/365cb7658cd8164573e7796d96f879bc/8eada/main.avif 750w,\n/static/365cb7658cd8164573e7796d96f879bc/7c608/main.avif 1080w,\n/static/365cb7658cd8164573e7796d96f879bc/a357f/main.avif 1366w,\n/static/365cb7658cd8164573e7796d96f879bc/c62e1/main.avif 1920w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.5208333333333334}}}},"excerpt":"…","fields":{"readingTime":{"text":"19 min read"},"layout":"post","slug":"/dev-ops/cache-and-restore-keys-in-github-actions/"}}},{"node":{"frontmatter":{"title":"Next.js의 API Routes 코드 모듈화에 대해서","date":"2023-07-26","tags":["Next.js"],"draft":false,"excerpt":"API Routes를 사용하면 코드가 매우 지저분해진다. API Routes를 사용하면서 어떻게 하면 코드를 보기 좋은 형태로 남길 수 있을지 고민한 흔적.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRlABAABXRUJQVlA4IEQBAAAQBgCdASoUAAoAAAAAJQBOmUI4G2AKEr3kT9TfSAd8bMV4y7BHP9V/MDjAP1APvhp9S1P4WAaWWwAA/v//FO+/uU2wVgdvo3t7+/esHdVnt/ADvJNu//kKsryq7K4/kH6dQSpGZH/Wmy5Hn/aiP/iWMNYE/L04/fxOh6w6LNfMVCO2e4bk1w+gWtpgjXx8dPwxbP/af/3X+0eo//xh3vW8bP8x/59L+P+uAb/nTz0WLfd1P3vPtBSZEyy/3T0wbRrtQDgzQWJR+Ionuv+3z/+oMGf/VUBr79zfpXfp+qM/6uI1nkf8xYssVf+Jam3g3/89o/+0Ec/+2AL9tBfn9QixAvY/zPVrT+ICoP+ly+1C7/DtZUF9PQRI4d13mrIY7dR2bGTX2cQVs9OgNCzOMwQy1nvlPj56aTR9Kl6iaLrR7askCAA="},"images":{"fallback":{"src":"/static/6763177ee50addd67c4dc57952797f69/231da/main.webp","srcSet":"/static/6763177ee50addd67c4dc57952797f69/7513b/main.webp 750w,\n/static/6763177ee50addd67c4dc57952797f69/317ed/main.webp 1080w,\n/static/6763177ee50addd67c4dc57952797f69/b5c49/main.webp 1366w,\n/static/6763177ee50addd67c4dc57952797f69/231da/main.webp 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/6763177ee50addd67c4dc57952797f69/7f171/main.avif 750w,\n/static/6763177ee50addd67c4dc57952797f69/4f36a/main.avif 1080w,\n/static/6763177ee50addd67c4dc57952797f69/dac68/main.avif 1366w,\n/static/6763177ee50addd67c4dc57952797f69/f7ebe/main.avif 1920w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.5234375}}}},"excerpt":"메타 프레임워크 Next.js는 react…","fields":{"readingTime":{"text":"11 min read"},"layout":"post","slug":"/nextjs/about-modularizing-api-routes-code-in-nextjs/"}}},{"node":{"frontmatter":{"title":"글또 8기 회고","date":"2023-07-16T11:03:47.149Z","tags":["Diary"],"draft":false,"excerpt":"6개월 간 참여한 글또 활동 회고. 글쓰기에 대해서.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAACE3AAAhNwEzWJ96AAABGklEQVR42qVSu6qDQBDNB+mP2EY7u+AHKAZ8QCCmElvB1i6CpT8gCHYqCvoJqSVX0Bt3nbsrCIGLoMnCsMM5s2cPM3OAlTNNE3zCHdaKu677resalWWJsyzDRVHgqqowxSi3JvxPEGM837fb7cmy7CiKIpIkCZ1OJ0RzhmFGy7Ke77VbHE7n83m0bRvSNIXL5QKPx2P5CFRVHTc7XAR1XadOZiwIAmiaBoZhAIppmrZfkDxCi2CSJMBxHERRBI7jUIdot6BpmiMJaNsW4jgG0kMIwxCu1+tnDmmfBEEA13XB93243+/geR7wPA+Koox7p0x7+HM8HrFhGJgIYFmW55xgiHC7pwx93w9kB195nqP3ILv4otxmh9+eP5BhGA/5lJZDAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/53fe681b532753855e5826673a894e9a/44f99/main.png","srcSet":"/static/53fe681b532753855e5826673a894e9a/44f99/main.png 674w","sizes":"100vw"},"sources":[{"srcSet":"/static/53fe681b532753855e5826673a894e9a/23526/main.avif 674w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/53fe681b532753855e5826673a894e9a/15c6e/main.webp 674w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.56973293768546}}}},"excerpt":"퇴사를 하면서 함께 일했던 분이 글또라는 모임을 추천해주셨다. 글또는 글 쓰는 개발자 모임이자 커뮤티니다. 글또에 참여하게 되면 예치금을 미리 내고,…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/diary/geultto-8-retrospect/"}}},{"node":{"frontmatter":{"title":"React Query에서 mutation 이후 데이터를 업데이트하는 4가지 방법","date":"2023-07-02","tags":["React-Query","React"],"draft":false,"excerpt":"React Query의 mutation 실행 이후 클라이언트의 서버 데이터는 변경 되지 않은 상태이다. 화면을 업데이트 하는 여러 가지 방법을 알아보면서, 어떤 상황에서 어떤 방법을 사용해야 하는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRgoBAABXRUJQVlA4IP4AAABwBQCdASoUAAsAAAAAJZACdLcA/QBsgFQLeUqiUmPP/FX1K/7b+WXGAfpWYGrQH48nJYXAAP75Cef4pKYwXWaObmj6uNb89cRstuX4oguTI/Ltf2477JAiP5FcA5Tr9O5n03ruT+hCFEwnvbQf/BHc/uRzjYa2s/8HBWpoTqXuNry0nN2zBDiF4JKFyMGG9jBPudMl/UEj/9A9E9V8kEV9HbR8TPpZ8PjBDRgmL//WUX/9Jdyf/h8/0tv5zn9dUvP2bq/zO9JfbQv/fIzX9/LxVAn65Vaj3P/7mf+ZIZJg7Y5yEOa4AftMEfMZvKFetXih4WkIv3/k5M/oAAAAAA=="},"images":{"fallback":{"src":"/static/848a29a42bca253c5a3a44c252c3720f/81547/main.webp","srcSet":"/static/848a29a42bca253c5a3a44c252c3720f/73e0d/main.webp 750w,\n/static/848a29a42bca253c5a3a44c252c3720f/9fede/main.webp 1080w,\n/static/848a29a42bca253c5a3a44c252c3720f/81547/main.webp 1200w","sizes":"100vw"},"sources":[{"srcSet":"/static/848a29a42bca253c5a3a44c252c3720f/4814e/main.avif 750w,\n/static/848a29a42bca253c5a3a44c252c3720f/acf79/main.avif 1080w,\n/static/848a29a42bca253c5a3a44c252c3720f/30577/main.avif 1200w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"React Query는 데이터 fetching 라이브러리로 소개되지만, 서버 상태 가져오기, 캐싱, 동기화 및 업데이트를 쉽게할 수 있는 라이브러리다. 즉, React Query를 사용하더라도 실제 API 요청을 보내는 것은 Axios…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/react-query/mutation-after-data-update/"}}},{"node":{"frontmatter":{"title":"한영타변환기 Alfred Workflow 개발기","date":"2023-06-10T20:25:47","tags":["Tool","Alfred","Automation"],"draft":false,"excerpt":"dlfjgrp Tjwlseks akfdlek. dlrp sjan Qkrclseks akfdlek. zzzz...","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAYAAAAywQxIAAAACXBIWXMAABYlAAAWJQFJUiTwAAABkElEQVR42mWR61LbMBCF/QJMgeCr7rIdX8IkUEJDTSAkhJlO3/99To9s0obpj09ar1fnrLRRYkqY+QKq7pGaCokukdkaN8qhqFqY9hai7pCXDTRj1fSIbYlvhcaVtLhm3TmR8A365RrN4h7ad1CuhS57CD+ncIWUBqmukAUz5RFLD01z19CIZ0P+nCjmgdBVzOKQKCgiXYWcbpl0SJkfhUhu52NN2a9Q3d5BVd1o+EVwxoOBWPOKxkERoTRedjt8/PqN7f4dT7s9lpsBF5nEpTS4yOUUC/P/lW/OxLR18M7hx/oRx8MRh/cj3vYHcsTz6x7d6gHt6jv6uzX6+zVMsxjf8dRUIIq55J9ixhiUpcfrMJBnbB43eNr8xHbYYhhe0HZLGA7H1S0sB1b4GjPtvgpmXCQFrbWfhGtbFMoiI0mAXcR8z5nwuBYOV4JdMZdq1pjphn8FJT+MdaNQ2LWZDArmw2BSTjWQkFhMUw5xzv+K9ZJkjBM9CUfnYuNATkJkFDkh/hHywTA8UxAdzfW0/wGce/nh9L2hXAAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/24a1413e882f06cfbb3af834a3ff3897/252b8/main.png","srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/13110/main.png 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/6f9ad/main.png 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/bf69c/main.png 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/252b8/main.png 1556w","sizes":"100vw"},"sources":[{"srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/8038b/main.avif 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/bbbaa/main.avif 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/60776/main.avif 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/6812c/main.avif 1556w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/24a1413e882f06cfbb3af834a3ff3897/b665d/main.webp 750w,\n/static/24a1413e882f06cfbb3af834a3ff3897/71b9a/main.webp 1080w,\n/static/24a1413e882f06cfbb3af834a3ff3897/9aed2/main.webp 1366w,\n/static/24a1413e882f06cfbb3af834a3ff3897/cf8f0/main.webp 1556w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.4717223650385604}}}},"excerpt":"요구사항 문서를 정독할 때 때로는 타이핑해서 옮겨 적는 것도 큰 도움이 되는 편이다. 편집기랑 창을 양쪽으로 분할 한 뒤 이해한 부분을 타이핑 하다보면 한글 타자와 영어 타자가 원하는대로 타이핑 되지 않는 상황이 꽤나 많았다. 내 맥은 CapsLock…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/tools/alfred-korean-english-converter/"}}},{"node":{"frontmatter":{"title":"React 렌더링과정으로 알아보는 선언적이라는 의미","date":"2023-06-05","tags":["React"],"draft":false,"excerpt":"React는 개발자에게 코드를 선언적으로 작성하도록 한다. 이것을 렌더링 과정과 ErrorBoundary를 통해 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAgEBQn/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/aAAwDAQACEAMQAAABweYFZJ8teBR//8QAGxAAAQQDAAAAAAAAAAAAAAAABAADBQYBAjH/2gAIAQEAAQUCjR2C5C+VWrQoix14okjVf//EAB0RAQACAQUBAAAAAAAAAAAAAAECEhEAAxMhMSL/2gAIAQMBAT8BsgwrtpJFmjyRqS6g+Vlkt1n5MPo6/8QAHBEAAgMAAwEAAAAAAAAAAAAAAQIDERIAEyIx/9oACAECAQE/AcAssm5QUV1EakdT7Mfpx90mCEINU72LyV5//8QAIhAAAgMAAgIBBQAAAAAAAAAAAgMBBBESEwUQAAYUITJD/9oACAEBAAY/AqNay40VrFpCnuWHaxSTYItNa/6MENkA2OR5Gx8o+Q+l/M2fJV7Nt9Ri7I8jCFL7FuNn2tTqcyN7acrIk6OlETG+gh9hzoVy64aw2QHLJLhBTMDyn8lMftkbuev/xAAZEAEBAQEBAQAAAAAAAAAAAAABEQAhEDH/2gAIAQEAAT8h6Fk+jilBsLYK5ITRA2JegnoZ+UgRRERGIjRE6I/HMu43R0mCBBaNCb//2gAMAwEAAgADAAAAEHAP/8QAGBEBAAMBAAAAAAAAAAAAAAAAARARIUH/2gAIAQMBAT8QDTk8RMdrFFsyB//EABcRAQEBAQAAAAAAAAAAAAAAAAERECH/2gAIAQIBAT8QXztwF1ZZogCVYv/EABcQAQEBAQAAAAAAAAAAAAAAAAEQEQD/2gAIAQEAAT8QaMl/Oh0+QwzMmgdfPJ2GwkqLnvDiAABBEQRE4KSc7UqTatEMf//Z"},"images":{"fallback":{"src":"/static/776ea9d9adf27d1450842a29d5b85c8c/a764f/main.jpg","srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/37bba/main.jpg 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/61c72/main.jpg 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/d61e8/main.jpg 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/ba386/main.avif 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/8adb1/main.avif 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/dc6b3/main.avif 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/776ea9d9adf27d1450842a29d5b85c8c/a66aa/main.webp 750w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/65dd5/main.webp 1080w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/4fad6/main.webp 1366w,\n/static/776ea9d9adf27d1450842a29d5b85c8c/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"라이브러리와 프레임워크 “The library for web and native user interfaces” (웹 및 네이티브 사용자 인터페이스용 라이브러리) 새로 개편된 React 공식 홈페이지에 있는 문구이다. 개편 되기 전 React…","fields":{"readingTime":{"text":"17 min read"},"layout":"post","slug":"/react/declarative-meaning-of-react-rendering-process/"}}},{"node":{"frontmatter":{"title":"React는 Hooks를 배열로 관리하고 있다","date":"2023-05-27","tags":["React"],"draft":false,"excerpt":"왜 Hooks에 이런 제약 조건을 걸었을까? React 내부에서 Hooks를 어떻게 처리하고 있는지, 이렇게 디자인 된 이유는 무엇인지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAPABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAQGB//EABcBAAMBAAAAAAAAAAAAAAAAAAIEBQf/2gAMAwEAAhADEAAAAciWdzbSDsCKIjn/xAAaEAACAwEBAAAAAAAAAAAAAAAEBQEDBgIU/9oACAEBAAEFAiWbCWhZcaMvvWhVL/Qs5tfmjBZse/c6uv8A/8QAIBEAAgICAgIDAAAAAAAAAAAAAQIDBAUSERMAMRQVIv/aAAgBAwEBPwHuy0VcWslbj+zrsKVcpM3XlzGw+OZVGPqGMc7flllZW0Cu7WNHiy2kaI8eRhdVCvFDJN0xuOA6RaOV6gwYR8ek19Hz/8QAHxEAAwEAAgIDAQAAAAAAAAAAAQIDBBITBREAFENS/9oACAECAQE/AfXjbztLIghnlP7KaNEBWsy8hnciGXVqbnBnZgtlgKCZ5Tn1N8fNiR2Q+OrfgxXulLD104kAMncnbxIH6haf2iN7Vf/EACMQAAICAQQCAwEBAAAAAAAAAAIDAQQFBhESExQiACEyIyT/2gAIAQEABj8CZPZSQyzWxOOswGTgSH/DpAvN4znyl3YMU/7MaddbOa4gYQHkHh7Wes0kYzDZqLa1NqpoW7OJDUbacQ5+oPEuMJM9Kzhv5IuiS92qwte7qDU67FXHMrmiulwJrdeVyeyAkdUUu2B33hkp32KA9ICFLbTSsvGtY9KrGSm5kGkdV9LR83MX4zBBi/FfaDhYXPBkWJFcdff8sJRfOsVVuIVVQJZFgsGoOp+FhfPktUx08wBkQQct/swAYLJUrdy6IWbtVz2X0VylwXbDuPWbFfQoemI4AK4j1H8z8//EABgQAQEBAQEAAAAAAAAAAAAAAAERADEh/9oACAEBAAE/ITx0G3wiSFZPGOYVO15TG2ShwhP/ALZwYOCLAH6xLFHJWuGyQixYPJQ1yGGhxB7u7E6VFeYBXH//2gAMAwEAAgADAAAAENgP/8QAGBEBAQADAAAAAAAAAAAAAAAAAREAITH/2gAIAQMBAT8Q0172QEviCR52c2FXwwpowfAgIf/EABgRAQADAQAAAAAAAAAAAAAAAAEAESEx/9oACAECAQE/EFHMmO7MLFgb9EzQudAjkFDWBv/EABYQAQEBAAAAAAAAAAAAAAAAAAEAEf/aAAgBAQABPxAMfwZF4vv+q3sVpyafabL76goYIhZaY/4fAZLG+ewVBNJiX2wyAhyCFMxF4qdqCGxqUZ//2Q=="},"images":{"fallback":{"src":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/4d5c4/main.jpg","srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/4d5c4/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/80a20/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/7dacabb3ac12d6aa95692bbc4ff21a03/ffef7/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.75}}}},"excerpt":"React는 Hooks을 배열()로 관리하고 있다. 이는 Hooks를 관리하고 있는 배열에 index로 접근할 수 있다는 뜻이며, 이는 호출 순서에 의존하고 있다는 뜻이다. (아래에서 예시로 든 코드는 보기 쉽게 Linked List…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/react/react-is-managing-hooks-as-an-array/"}}},{"node":{"frontmatter":{"title":"왜 TypeScript는 void 타입을 사용해도 값을 return 할 수 있을까?","date":"2023-05-09","tags":["TypeScript"],"draft":false,"excerpt":"TypeScript void 타입을 조금 더 알아보기.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAcBAwYI/8QAFgEBAQEAAAAAAAAAAAAAAAAABgIJ/9oADAMBAAIQAxAAAAFV827OdRxlosxJH//EABsQAAMBAAMBAAAAAAAAAAAAAAMEBQIBBgcS/9oACAEBAAEFAiJzxed6toA12W0paqJXWAIlqa3wff0T/8QAHxEAAgICAQUAAAAAAAAAAAAAAQIDEQAhEiIjMUGB/9oACAEDAQE/AW4vrQ7caNY5ElUVS3it0fePCkjNI9lnJZiOmydk0tAfBn//xAAcEQADAQEAAwEAAAAAAAAAAAABAgMEBQAREzL/2gAIAQIBAT8Bw8rs5H6C0pXRHT1OlriRvOaU8+zZfRKKJJDUMkqIHLH39RRkZVZUXn8+WHBixIGCZMufOgetLsFjJEUG1matSAvr6UZnb9MSfP/EACgQAAIBAwMCBQUAAAAAAAAAAAIDAQQREgUTIQAUFSIxQbFRYWNxgf/aAAgBAQAGPwLQ6ypNu8zWtb7dKjUe5tpo926xyaGMAESTNvli8IMNw1gfhpNXx5Nx+Z/bLMeT5tjb6e43LUaOhnT1OpKAJpScT8GU1GmmZZh+chKVZDlMzETa8+vS6GUU7UKY1oTO8p134ZiTadypYu4RIAzMQmSkYjIr37Sit+RROn95sZJTPx6R0RYiN/YImB/kXn56/8QAGhABAQADAQEAAAAAAAAAAAAAAREAITFBUf/aAAgBAQABPyFgE3wgi0ZYqwW8GWCgPqLUQJSOuXaYcHdXocBKdzvIjLCDAWkpkgGoADU02A+rpwM6o9SJ9opeu21z/9oADAMBAAIAAwAAABCQ7//EABoRAQEAAgMAAAAAAAAAAAAAAAERACExQXH/2gAIAQMBAT8QmDU7wKQgWgqIteK8NUBcBXO4AXzP/8QAFhEBAQEAAAAAAAAAAAAAAAAAAQAh/9oACAECAQE/EJXi2BlnEVKwWMAFxc74bFqv/8QAFxABAQEBAAAAAAAAAAAAAAAAAREAIf/aAAgBAQABPxCbD0xshesT6MATaBCRMug8QbrHlzLcfZdbU8WfJ+A6cYFfKjWvsw9CZ9FQAGZzrVsZaPKEnoCCB//Z"},"images":{"fallback":{"src":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/8ad6a/main.jpg","srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/8ad6a/main.jpg 637w","sizes":"100vw"},"sources":[{"srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/0a6a0/main.avif 637w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/6f6b5eaafc9d6028faebbb4ea16c26fc/85b8e/main.webp 637w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671899529042387}}}},"excerpt":"void의 기본 선언 방식 void는 TypeScript에서 흔하게 사용하거나 추론되는 타입이다. 주로, 함수에서 이 없을 경우 return 타입으로 void…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/typescript/why-can-typescript-return-any-value-using-void/"}}},{"node":{"frontmatter":{"title":"TypeScript의 기본개념과 환경설정","date":"2023-05-05","tags":["TypeScript","Environment"],"draft":false,"excerpt":"TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMElEQVR42mP4////v38oiHjAANKMikjTjAaA+v+imvH3H27NNbufm0+/5Tb/rvPcOw5z7px9+g0o+Psv1JR/MBMxnQbS7L/wLkP2aZbiswwFZxiKz2658fHll98/fv/7B1YLpO+8/fnjD8iYX3/+AQ399usvQrP3onsGU25mbHwcsPS+xYxbyy6+33X747bbH1ddfT///Ntll9/3Hn+14cYHIHfllffTTr/ZdPMjxC0gzW4L7ir3Xs/Z8iR+7aO6Pc833/j4/fe/vfc+A/UffPD5xJOvF55/O/X065VX388//7bxxscH739CQgGk2WvhPa66i46z7wCtLdj6dN/dz0BBoH6sYYnu54cffl588R2Irr36DgytTz/+QiMfHGCQMEMgpLTAgCsOiUktDP8pAAA9+2KaOzXrLQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png","srcSet":"/static/e092969a3269e232f50e03e941f3d22f/38824/main.png 750w,\n/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/2f802/main.avif 750w,\n/static/e092969a3269e232f50e03e941f3d22f/820f8/main.avif 800w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/24bb5/main.webp 750w,\n/static/e092969a3269e232f50e03e941f3d22f/a78a0/main.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5475}}}},"excerpt":"TypeScript를 사용해 개발 하는 단계는 크게 3가지로 나눌 수 있다. Lint stage Compile stage Runtime stage Lint stage는 개발자가 코드를 작성하는 시점이다. Compile stage…","fields":{"readingTime":{"text":"16 min read"},"layout":"post","slug":"/typescript/typescript-env/"}}},{"node":{"frontmatter":{"title":"JavaScript MVC 패턴으로 만드는 SPA","date":"2023-04-17","tags":["JavaScript","Design Pattern"],"draft":false,"excerpt":"모던 JavaScript 프레임워크 없이 MVC 패턴으로 SPA을 만들어보자","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAcGCf/EABcBAAMBAAAAAAAAAAAAAAAAAAMFBgf/2gAMAwEAAhADEAAAAejWSqkKItsIj9K//8QAGRAAAwEBAQAAAAAAAAAAAAAAAQIEAwUR/9oACAEBAAEFAtZBllDfJ09EjXy52GXJASoE+f/EACMRAAIBAgQHAAAAAAAAAAAAAAECAwURABITMQQGFCEjYdL/2gAIAQMBAT8B5W42CStpTZEbp3iIlGkjsXALo0baiFO4s984tsmY3DUalXPhbf19Y//EACIRAAICAQEJAAAAAAAAAAAAAAECAwURIQAEEhMjMWFxkf/aAAgBAgEBPwGxinNZNvcbATxlWhPMZVCllVw4EbcWjHAGMnuwA1FjZYHWT568bf/EACMQAAICAQMDBQAAAAAAAAAAAAECAxEhABIxBBATIiMzUfD/2gAIAQEABj8Cknm+OJGd7IUUPsnA/DHOm6dIirQjd5vCY0KjFFx7bE36cknXOnW8FSCMURXB1NEgCR772IAi3xdLQuu3/8QAGRABAQEBAQEAAAAAAAAAAAAAAREhMQBB/9oACAEBAAE/IV6j0AO1YB3UGDahhLNfhFLgYAFFlQkjwS4spCEE0TEcTvrAeu37SThUsznhAF4e/9oADAMBAAIAAwAAABAEz//EABoRAQEAAgMAAAAAAAAAAAAAAAERADFBofD/2gAIAQMBAT8QZloxFp3BGG5Etiak5RR870n/xAAbEQADAAIDAAAAAAAAAAAAAAABESEAMUGx8P/aAAgBAgEBPxAxiUbeESFkAQMWBCg67Px5z//EABkQAQADAQEAAAAAAAAAAAAAAAEAESExUf/aAAgBAQABPxDRnqoVcsCvthYHqoFiJoAIus458RarRw4mPl28lZdoMBAjjZIQIy7NKcqgfWLBkmIUkFAc4T//2Q=="},"images":{"fallback":{"src":"/static/5349dfe902fbdb7676264f2e7aae8a83/3440d/javascriptMvc.jpg","srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/3440d/javascriptMvc.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/3d183/javascriptMvc.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/5349dfe902fbdb7676264f2e7aae8a83/17574/javascriptMvc.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"모던 JavaScript 프레임워크는 여러 패턴을 따른다. MVVM 패턴, Flux 패턴, Component 패턴 등. 다양한 문제를 해결하기 위해 다양한 패턴이 생겨났다. 이번에는 예전부터 사용되어온 MVC 패턴을 JavaScript…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/javascript-mvc/"}}},{"node":{"frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","date":"2023-04-05","tags":["Bundler","Webpack","Environment"],"draft":false,"excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/885fa/main.avif 750w,\n/static/398ff7eccce15fa106b9755da8007778/4f36a/main.avif 1080w,\n/static/398ff7eccce15fa106b9755da8007778/dac68/main.avif 1366w,\n/static/398ff7eccce15fa106b9755da8007778/97f05/main.avif 1720w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}},{"node":{"frontmatter":{"title":"노드 버전 매니저 툴 비교기(nvm & fnm & Volta)","date":"2023-03-28","tags":["Tool","Node.js"],"draft":false,"excerpt":"nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAYIB//EABYBAQEBAAAAAAAAAAAAAAAAAAgABP/aAAwDAQACEAMQAAABzdRanF4HOXiqjdf/xAAbEAADAAIDAAAAAAAAAAAAAAADBAUABgIRM//aAAgBAQABBQKXc4P7FIdqB2RnTm2DzwADY9C9Z//EACERAAICAQIHAAAAAAAAAAAAAAECAxESADITISNBUWGz/9oACAEDAQE/AZHEsTBC2fGYHMclUBdhSQWbJ3qwpvKhj1u01ehFAB8tf//EAB4RAAICAgIDAAAAAAAAAAAAAAECAwQREgUhAAZC/9oACAECAQE/AWkq05ZVjoxtBZ4uvC4lkZ2FrJaWwgIwm/QUbnTTYDZ8ovt/LIqosihVAVRonQGAPnz/xAAjEAADAAEDBAIDAAAAAAAAAAABAgMRBBITAAUhURAxFGFx/9oACAEBAAY/ArdgoITYNecaz1ILcqY4E1ClSsucnaMMcMUUgbsjufJPWfgsmpEeS6WkaPSWx1k52wWa7wNmWxkZOerVfuFjvrRlHGmFVnLBFxjCrnx095Qit3oGa3FM23DOGWpUvNv2jKfA9Dpqvg0fyzYAyffjA/vv7+/j/8QAGhABAQEBAAMAAAAAAAAAAAAAAREhADFRcf/aAAgBAQABPyGd8BiLfFbtzXdG5MsdLkmOVS+8BSA3cAogn3XgYaEioKRBuNFwWKV1y0UGjCg1VUvR67//2gAMAwEAAgADAAAAEMPf/8QAGhEBAQADAQEAAAAAAAAAAAAAAREAITFRof/aAAgBAwEBPxAexpMR3yonIOcd3TtAgowABz7emf/EABgRAQEBAQEAAAAAAAAAAAAAAAERADHw/9oACAECAQE/EFrNNxOKAECFJguX5iMAXwHy7//EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxYf/aAAgBAQABPxBOeyTtu7phz5c5dwE8139VQEMhMbyGwbLNpFBZpWuvKq2XlKc0Mv4kmwLUoPi3fJ3/2Q=="},"images":{"fallback":{"src":"/static/fa6657a7573785fcabeb321f5d546e59/3440d/node-version-manager.jpg","srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/3440d/node-version-manager.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/3d183/node-version-manager.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/fa6657a7573785fcabeb321f5d546e59/17574/node-version-manager.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"모두 Node.js의 버전을 관리하는 툴이다. 가장 먼저 nvm을 시작으로 Node.js 버전을 관리하다 fnm을 알게되었고, 추가로 Volta를 알게되어 세가지 툴의 속도 및 방식에 대해서 간략하게 알아본 정보를 정리해본다. nvm 먼저 nvm…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/node/node-version-manager/"}}},{"node":{"frontmatter":{"title":"다시 보기 위해 적어두는 URI 구조","date":"2023-03-16","tags":["Network","URI"],"draft":false,"excerpt":"하나의 주소 안에도 여러가지 용어가 나온다. Host, Domain, Site, Origin등이 그것이다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAABQAGB//EABcBAAMBAAAAAAAAAAAAAAAAAAQFBgf/2gAMAwEAAhADEAAAAe1oHMaIvZsVU4f/xAAZEAADAQEBAAAAAAAAAAAAAAACAwQBEyP/2gAIAQEAAQUCfZlsi5jaHsClyTPR2coSrpzf/8QAHhEAAwABBAMAAAAAAAAAAAAAAQIDBAAREiEUIzH/2gAIAQMBAT8BzVrjeEZCcBbDjf1sXYsWIFCaTJSjFN2EzxXrie21sx73+6//xAAhEQACAgIBBAMAAAAAAAAAAAACAwEEBRETABIUFSExQf/aAAgBAgEBPwH18561lJrW2bx+XZjLC7ioUsVgC7DV1vFYXKsV21ClliBMy5eQBEVbDDmILGbHyAAEzAzqZARGZ+/3t31//8QAJRAAAQQBAwQCAwAAAAAAAAAAAQIDERIhAAQxBRMUIkFRUmFx/9oACAEBAAY/AmnvN7Dw6g7tfD9bvdu4umh7qSipXlJbUnnJTqUM9WdTYpvCVIvE1JG1A5zAhX7GmEUdKkNUX6qJshxxJCpk2xmc63G6caB3G1fhh0FSFN2UEqihTMjBtOqNvPIRN6h1ytvyraLY551h5z75+Tyf7r//xAAbEAEBAAMBAQEAAAAAAAAAAAABEQAhMVFBYf/aAAgBAQABPyEmEq4KpKTB+gIidAWmowEigA1oc9kSC6gCIhp+5E9lxag1bA0yesUuZOy4OeO4xitUe0VPU7V2vc//2gAMAwEAAgADAAAAEFDf/8QAGxEBAAICAwAAAAAAAAAAAAAAAREhMUEAYXH/2gAIAQMBAT8QCn4qqJsWViCSOYK2WMrbo30ec//EABgRAQEBAQEAAAAAAAAAAAAAAAERIQBB/9oACAECAQE/EHaeIKbsX3YE3C7MtAO0O1otS+9//8QAGBABAQEBAQAAAAAAAAAAAAAAAREAITH/2gAIAQEAAT8QI6tAWWqOJOKHD5dc9V9LDQPIxGBss3rElxwNYqu6gF9VPypFaCMZplJFSGB8QAGKqOFWcnUmshUu/9k="},"images":{"fallback":{"src":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a764f/main.jpg","srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/37bba/main.jpg 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/61c72/main.jpg 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/d61e8/main.jpg 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/ba386/main.avif 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/8adb1/main.avif 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/dc6b3/main.avif 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/ebfaee9be1f3a6861c8c85af1fb70c6d/a66aa/main.webp 750w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/65dd5/main.webp 1080w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/4fad6/main.webp 1366w,\n/static/ebfaee9be1f3a6861c8c85af1fb70c6d/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"프론트엔드 개발자로 일하면서 다양한 네트워크 용어중 주소에 대한 용어가 항상 헷갈렸다. 하나의 주소 안에도 여러가지 용어가 나온다. , , , 등이 그것이다. 이전에 토이 프로젝트를 호스팅하기 위해 도메인을 구입하고 AWS…","fields":{"readingTime":{"text":"11 min read"},"layout":"post","slug":"/network/uri-structure-written-down-for-replay/"}}},{"node":{"frontmatter":{"title":"React의 클래스형, 함수형 컴포넌트 차이","date":"2023-03-05","tags":["React","JavaScript"],"draft":false,"excerpt":null,"image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsSAAALEgHS3X78AAACf0lEQVR42i2STU8TYRSF+xPc+ANc+A9cundjXBl0oTHuXKorE43RoAtNCBWQj0KBClRKQQSK2A86ZdpSoGWGKYXSgkSQsEHQ8g3t9PHO4OIm73nvzH3PPec4ynor1UI/Zt5LxTpnXbDqg6KX6oKF2wUPwErfBV50Cx4U3Cu4BVNwteDDXPJQ1ppxIKCSdWPKx6d6G0dGN8eZVkrT9eynWwV7OEy3cDDTwJHWzqHWyX6qkf2E9OfaOMt2YsqjNrF8Hw5z5TMYLnYSTuKJcUIplZHQGNFZFdWYJzitEggHpMYIpuLEs7rcZ1AWMqj5PGpygl21DnKdVIv9OM7nm2G5i7mYj8wZjLhq6a65SrT4g0IFFD1HdOO3XYqxjFE6Ibm+SWB8iK/9LobDQWbjQyJBD+cLLmFotAtlN4Ye5vvPXRpuXSF+5xLOV48JG0tE17cJlGDsD0zKuTcyhdvvo/XZPd7cvUbTk9tEQqK5aGmt7WDVTzndgJ4O4M8s0/fyAZ7n94nkVoTJL0LFTcZl4OhfGbi2hV9J8PBtHZdv1nD9xTuetnxiPvmF8ly9bY5o6AW9kUzMy0hug4is1jM1R2Jrm0K5QnRhGWVjh0mpWDbPYumY2sEJbrx28mgwxvuIRjrUJQxdmEWfpeFHOxJ7mgdVGWY0/E2MmBLxNWLaDMGkwng0SGBygon4JHExJLVkoM6nUGZUlLCPvYzbjlpZk5UrImTVYlnwcjLr5HC2iWOJzkGmjf1kvY2Psh6OdDcHqQ92ZA41t90vJZ2cWqauXeSwordYGg7YppSFqZnvlaafas5th5hCn43JdvzH8vDagIS7A9Nok/D3U5X/LTOsYRaxfy7ok/GBEcEZAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/eaa081aa6f5f962aab7f962d4692e442/62ea7/class-functional.png","srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/62ea7/class-functional.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/f1cd5/class-functional.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/eaa081aa6f5f962aab7f962d4692e442/2fa07/class-functional.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5}}}},"excerpt":"react의 class, function 컴포넌트 차이 Class 컴포넌트 Class 컴포넌트로 Counter를 만들어보자. react 라이브러리에서 제공하는 Component를 import 받아와서 상속 관계를 맺어주었음. 따라서, react…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/react/class-functional-component-difference/"}}},{"node":{"frontmatter":{"title":"객체지향 프로그래밍으로 알아보는 prototype","date":"2023-02-24","tags":["JavaScript"],"draft":false,"excerpt":"자바스크립트가 만들어진 기반, prototype 언어가 가지는 근본적인 철학에 대해 고민해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAYIAQn/xAAWAQEBAQAAAAAAAAAAAAAAAAAEAQL/2gAMAwEAAhADEAAAAeH9vQC4HymGlR//xAAcEAABBAMBAAAAAAAAAAAAAAADAQIEBQYHExX/2gAIAQEAAQUCro7JMvKtZUldrdWvegTGE42SXvnCTon/xAAfEQEAAgIABwAAAAAAAAAAAAADAQIEEQATFCEjsdL/2gAIAQMBAT8ByuqU8eowNRFIRPIpMr3bu63rS8tA4xqJYdrHipZec1ZYyQ4gdRuqb1G9Xr8T7nj/xAAfEQACAgEEAwAAAAAAAAAAAAABAwIEEgARE1EUI/D/2gAIAQIBAT8BMZngxsFBW/N4FZNgWqwQ6HhgtlE1OSwxFidtIlYgK/DD1uaDnt93se9f/8QAJBAAAwABAwQDAAMAAAAAAAAAAQIDBBESIQAFEyIUMUEGUYH/2gAIAQEABj8C2ZG7Rpz8KH1d+AyvwjhozgKUp97kA4dtB12z+R9s7lLuWZXIfMfMxBR8H4VaY0fhoCC8FlbLm+LO8/K4+XW7I+kEQym3C6PtG5S4ZtSNeV426jn2BOuh0EaSrRKY7StB1YhpV3j3Q6+p9E+v66t2le55M+25OTLKvgyKxxnssZuD4pKiqnkAoZIFi1QKMhcBumZ9Sd553N+6Mfo/rMT/AL1//8QAGhABAAMBAQEAAAAAAAAAAAAAAREhMQBBYf/aAAgBAQABPyHebPfjkkCtuRypmwVKmDQzuRJw5JLlhMJ2pQOJ2iI9MKWNQIwbIpgaMpsYHC7ySD7QZxBYvq7/2gAMAwEAAgADAAAAEDzP/8QAGBEBAQEBAQAAAAAAAAAAAAAAAREhADH/2gAIAQMBAT8QaswvAJb0iLpLsDoBFhUFgdlTyq17/8QAGREBAQEBAQEAAAAAAAAAAAAAASERMQBR/9oACAECAQE/ECYYww/XCiE/ZdMQ7vF+DUQoQAgBD//EABkQAQEAAwEAAAAAAAAAAAAAAAERACExEP/aAAgBAQABPxCyXz81zDXQ3wbfOHxxtRg0YJyqfnu2GKzB36Ui0YLQlk9CLgfu6kvMIP4Fmmr4KVUKVkKVZeB//9k="},"images":{"fallback":{"src":"/static/3742ab40c4a37d6d517fd4a6db47a830/d097c/main.jpg","srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/37bba/main.jpg 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/d097c/main.jpg 850w","sizes":"100vw"},"sources":[{"srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/ba386/main.avif 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/3d8d8/main.avif 850w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/3742ab40c4a37d6d517fd4a6db47a830/a66aa/main.webp 750w,\n/static/3742ab40c4a37d6d517fd4a6db47a830/873af/main.webp 850w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5623529411764706}}}},"excerpt":"객체지향 프로그래밍 객체 지향 프로그래밍(Object-Oriented Programming, OOP…","fields":{"readingTime":{"text":"22 min read"},"layout":"post","slug":"/javascript/prototype/"}}},{"node":{"frontmatter":{"title":"Event Loop와 비동기","date":"2023-02-16","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. await 키워드를 만나면 async가 붙은 함수 전체가 MicroTask Queue에 담기는 과정까지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAQUAAAAAAAAAAAAAAAAAAAEDBwgJ/8QAFQEBAQAAAAAAAAAAAAAAAAAAAQX/2gAMAwEAAhADEAAAAcOpgrUlkaAjP//EABsQAAICAwEAAAAAAAAAAAAAAAEEAgUAAwYh/9oACAEBAAEFAqCgZ6BpvjdFEvkCRKR9z//EABwRAAICAwEBAAAAAAAAAAAAAAECAwQREhMQMv/aAAgBAwEBPwGq8kF0WJDFPWX5qPChBfC4Lu/QOu2Sy8xsjaqY3US+f//EAB0RAAMBAAEFAAAAAAAAAAAAAAIDBAEABRIUFSL/2gAIAQIBAT8Bnu6dPHoeqxt+qavzXU6wAYZnuNXGaSn+UaKexgsMSw6FOW4k7Nz/xAAlEAACAgAFAgcAAAAAAAAAAAABAwIEAAUSEyEQERQVMUFxkbH/2gAIAQEABj8CZVqk61q3StNexcttGoR0VKNWDLFpnPcxgAIwBlKQGGDMWU7VjbLb0XWp5fcyFPh5sQqxlrpLs+Z2W6RCvtvA4URGU5yhgEEgjkEHsR8EcjB/ff79en//xAAbEAEAAgIDAAAAAAAAAAAAAAABESEQMQBBYf/aAAgBAQABPyFsXWo8jFj8nVtuKuYqFMmIYtB/zSZxpUJ6JxF1lWVWltVWXtWXH//aAAwDAQACAAMAAAAQlA//xAAXEQEAAwAAAAAAAAAAAAAAAAABACEx/9oACAEDAQE/EA7KIoM77buHBP/EABYRAAMAAAAAAAAAAAAAAAAAAAEQMf/aAAgBAgEBPxCU+3KzBB04RV//xAAaEAEAAgMBAAAAAAAAAAAAAAABEBEAITFh/9oACAEBAAE/EOEHTHdeoqBTJ+EATyAXZG1kj3t1w1rxT3G1Oo3lt5dVRFVVY//Z"},"images":{"fallback":{"src":"/static/e2f3938297514483cd217adbed0eb153/3440d/main.jpg","srcSet":"/static/e2f3938297514483cd217adbed0eb153/3440d/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/e2f3938297514483cd217adbed0eb153/3d183/main.avif 640w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e2f3938297514483cd217adbed0eb153/17574/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"요약 JavaScript는 싱글 스레드 언어이다. 하지만 멀티 스레드 처럼 동작하는데 이는 Event Loop 때문이다. Event Loop는 JavaScript Runtime Environment에 있으며 Web API와 Call Stack…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/event-loop-and-async/"}}},{"node":{"frontmatter":{"title":"JavaScript의 Symbol에 대해서.","date":"2023-02-15","tags":["JavaScript"],"draft":false,"excerpt":"Symbol은 도대체 뭘까? 어디에 사용되고 있을까? 조금 더 깊게 들어가서 알아보자. 나중에 라이브러리를 만들 수도 있으니..","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAIAAAAmMtkJAAAACXBIWXMAAAsTAAALEwEAmpwYAAAB6klEQVR42k2SW0/iUBSF+wuUUkqBci/Xckc7eIEQQEcBqa3MixMd541hEoOO8Ufoo/5hv842xOQ0Weecvddea/UoppnSND2VyiSTaUAikUyns/G4KUDXje0thwCWYcTZApRyuXpz8wuKXM4CNJtt7o6O+oBoNOa6l7e3wW0+X+j1DqVnPD5hC1ZqtcZ6/RfWQqH09vY+GAwZtVhcUkrz4+O/l5dXVLRanfv7TSyWyGbzm82Dbdc5VPhCobDoQSRDUCvCAOFwZHdXBbClkhowpJ+yq9Xa2dmUI9pGo0mxWAYcHBzigjl7ew5aDCNRKlXG4wll9Mxmc8v6LxsBeKABYk7r9SY9FxeueKbZ83wAsn1/CSMGff/KtmufshH2NUbot7FHIlEWV7Crqia3W3cKOlerP5ZVhPLp6bnd7lI9mZxggZPz86nnXTGwUrHv7n7LZH4BQgBKt7t/ff1Twlit1p1OF5Gk0Gi0mOO63nL5A8PMmE5n1JD26el3WALPEOzshEQ2bbBkMjlNi+IcYaoaIXCJWvSzADIskD0cjvDAms8XvBmcHx8PCEzXY47zjbQh5af0+wMYAejHXSAbGUiVB+g4PTHPy4FUACz0sAUwkLcFCxQMU74+WookT4okT4DELv9SXgvSTDOQ/QEcpXpIs5JmFQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/561bcd4a1b332dc70475a85d77d3c82c/cabd0/main.png","srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/d734b/main.png 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/cabd0/main.png 876w","sizes":"100vw"},"sources":[{"srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/c0126/main.avif 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/42e5c/main.avif 876w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/561bcd4a1b332dc70475a85d77d3c82c/59596/main.webp 750w,\n/static/561bcd4a1b332dc70475a85d77d3c82c/d99ef/main.webp 876w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6255707762557078}}}},"excerpt":"요약 Symbol은 primitive type으로 ES6에서 추가되었다. Symbol은 변경 불가능한 원시 값이며, 고유한 ID의 역할을 한다. 객체의 속성(프로퍼티)의 key로 사용된다. Symbol…","fields":{"readingTime":{"text":"14 min read"},"layout":"post","slug":"/javascript/symbol/"}}},{"node":{"frontmatter":{"title":"클로저와 함께 알아보는 curring 함수","date":"2023-02-14","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript의 클로저를 통해 currying 함수를 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAgFBwn/xAAXAQADAQAAAAAAAAAAAAAAAAADBAUG/9oADAMBAAIQAxAAAAFv4K0md1l1IjQceH//xAAcEAEAAQQDAAAAAAAAAAAAAAAGBQECBAcDFyL/2gAIAQEAAQUCV5zt8YF7Awy8V1HMqr98IJksAJQMOeguWvv/xAAhEQADAAICAAcAAAAAAAAAAAABAgMEEgURABMUISIzUf/aAAgBAwEBPwGmZ3jej8mYzDY0bkR9hmVmEisyCFCMKnbf5CoFEcymyrwGA6h6SNKONnd622dj7lm6cDsn8AHj/8QAIREAAwACAQMFAAAAAAAAAAAAAQIDBBEFABIxExQWIiP/2gAIAQIBAT8BXLw5yBrx61g9iYQW7ofx198i+jQs3cFcRE1dCwT0NJr5Zzw0JZvt5AAThCMFjFBoLKSmbETQAKoLE68k+ev/xAAhEAACAgEEAwEBAAAAAAAAAAADBAECBQAGERITFCIjM//aAAgBAQAGPwLMRtlCmF2m2GEobbredwZ1Fhga7jCQInrj0/BYluZqQ5RRb9Y5uKmQ2Olj65tzbLI8PgBYNUnGS8lLmJ7Q6RYlCLltHtlikkMa5O3Wa+XRM7u/OMY/Mv3klkEl1WhpL8RAFrEJfpUgq8xIl5sEVeo+5CQQloNt54mJMw8ljblTqKhaJGmBXCuSRzZT8/ihVZCYUfyJTWMSw2PXQB6K5b+KJsYxmRUOwZlos3aaMY17EKVgxSXmfq08Rqdf/8QAGhABAQEAAwEAAAAAAAAAAAAAAREAMUFRYf/aAAgBAQABPyGMncLZW4pAraiZ78snkTfJtGpmhaK/gJHOt/VfwXFQbiEQgN03jTRRco5gA0Ph5v/aAAwDAQACAAMAAAAQWy//xAAXEQEBAQEAAAAAAAAAAAAAAAABESEA/9oACAEDAQE/ELYYaMhglMI7oOW5DVLUS1OgsAgf/8QAFhEBAQEAAAAAAAAAAAAAAAAAAREA/9oACAECAQE/EF7DFqQ17Ci20BIUGtBO2KiCqv/EABgQAQADAQAAAAAAAAAAAAAAAAEAESFh/9oACAEBAAE/EGwbuUhhs4jmQXnbmsGuGEIEzc3DFfJpe78TiHQDRrFWRM5dEmj2ZEpi6EjQAAADcCqDhk//2Q=="},"images":{"fallback":{"src":"/static/dab08fdc28c522cf2d5cbcd40daae646/a764f/main.jpg","srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/37bba/main.jpg 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/61c72/main.jpg 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/d61e8/main.jpg 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/ba386/main.avif 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/8adb1/main.avif 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/dc6b3/main.avif 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/031aa/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/dab08fdc28c522cf2d5cbcd40daae646/a66aa/main.webp 750w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/65dd5/main.webp 1080w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/4fad6/main.webp 1366w,\n/static/dab08fdc28c522cf2d5cbcd40daae646/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"excerpt":"요약 일급 함수란, 함수를 다른 변수와 동일하게 다루는 것을 말한다. 클로저는 함수와 함수가 선언된 어휘적 환경(Lexical Environment)의 조합이다. Lexical Environment의 Lexical Scope…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/javascript/closure-with-currying/"}}},{"node":{"frontmatter":{"title":"왜 내 z-index는 먹히지 않는가?","date":"2023-02-11","tags":["CSS"],"draft":false,"excerpt":"z-index가 때로 적용이 되지 않는 문제를 해결하기 위해 stacking context에 대해 정확히 알아본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAJCAIAAAC9o5sfAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAt0lEQVR42mP4TwFgQBf49w9Efv3y/9GD/4+f/P/7lxTNf/6AyK0b/hqrfQty+vb+9V+4icRoBqleveqWq4bPzjDfc+nXv9wFCvz995coZ4NUvXp34fgK2cPh/FOOGE37tu8OSOLPX4Kagar+gxz5/s+7GXd38pX+Yoj9v+AYSPw3MZpB+v8CTfj75ef/3M1/w5b/O/LgH9jlxGkmM6r+gQP206dPz549e/HixbPnL548fQbkYtUMAEiyAT3z+KCbAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/de2246ea0f89f0544a92309e56a239d4/460e0/main.png","srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/88589/main.png 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/60f9b/main.png 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/914ba/main.png 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/460e0/main.png 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/a6926/main.avif 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/c7a17/main.avif 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/a79a8/main.avif 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/49852/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/de2246ea0f89f0544a92309e56a239d4/79ae4/main.webp 750w,\n/static/de2246ea0f89f0544a92309e56a239d4/06a55/main.webp 1080w,\n/static/de2246ea0f89f0544a92309e56a239d4/d2e17/main.webp 1366w,\n/static/de2246ea0f89f0544a92309e56a239d4/41672/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.46197916666666666}}}},"excerpt":"요약 z-index는 겹치는 요소의 쌓임 순서를 제어한다 z-index는 position이 static이 아닌 값을 가진 요소에만 영향을 준다 stacking context는 z-index에 영향을 주는 그룹이다 stacking context…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/css/stacking-context/"}}},{"node":{"frontmatter":{"title":"JavaScript에서 배열은 객체다","date":"2023-02-10","tags":["JavaScript"],"draft":false,"excerpt":"배열이 객체인 이유와, 유사 배열 객체와의 차이점을 알아본다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAcIBv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhADEAAAAZAZ0D6kX4uw/8QAHBAAAgICAwAAAAAAAAAAAAAABQYCBwERAxMX/9oACAEBAAEFAkrjUIq3Wh6sqIzDQItiwgIz3G1dsbEZaSP/xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/AT//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/AT//xAAmEAABAwQCAQMFAAAAAAAAAAADAgQFARITFAYRFQcIIhYjMTI2/9oACAEBAAY/AoXeR6LoeayiH+o2PNJScyVdKc5H5IpC49wauqFwhgCv2NdjxMlKK5gca7bfbz11b14/1Gt6tIC3bxd2Wuyh3vzidOuQ93cHGoZVRKeL0aEZMl3cQHJN4UhcVhFoj5fp/GOPhY5ZlSlKiJ3BUxO01q0h4bkriNjWIKjaNGrSNGgFF0dkWpFdK/MRwXdI4qqpySDdhIrJV9Gx7ht/Xu+rv10omzrI3+GPx9mKyhQYrceo8k2VupKyQXfl557WRkyNwhK9IFuI50ApUYauFtwh2CoHRIqHNebCMQqkxiGlP//EABwQAQEAAQUBAAAAAAAAAAAAAAEAESExQVGB8P/aAAgBAQABPyFEIsGhy66qJt36J/g5MyQtpQLQgubCGKY58KA0XVicEMW+nO/UJbl2gVLi1ELNziX/AP/aAAwDAQACAAMAAAAQ8w//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAEDAQE/ED//xAAUEQEAAAAAAAAAAAAAAAAAAAAQ/9oACAECAQE/ED//xAAYEAEBAQEBAAAAAAAAAAAAAAABABEhQf/aAAgBAQABPxCp44fqOPdZujYM2ocIb0HUwqGTYBN8M+Cqmxwuh9LVxprXfojXm8Dz/IG3ixeD46kTRURL/9k="},"images":{"fallback":{"src":"/static/e0c03ecf4f47788bcd911b8d79b30507/bcda9/main.jpg","srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/bcda9/main.jpg 612w","sizes":"100vw"},"sources":[{"srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/90af2/main.avif 612w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/e0c03ecf4f47788bcd911b8d79b30507/2fed0/main.webp 612w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5637254901960784}}}},"excerpt":"요약 자바스크립트에서 배열은 인덱스를 키로 갖고 있고, length 프로퍼티를 갖는 특수한 객체다. 배열의 prototye…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/javascript/array-is-object/"}}},{"node":{"frontmatter":{"title":"JavaScript의 Getter / Setter","date":"2023-02-09","tags":["JavaScript"],"draft":false,"excerpt":"객체의 접근자 프로퍼티인 Getter와 Setter에 대해 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAAOABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYEBQf/xAAWAQEBAQAAAAAAAAAAAAAAAAADAQb/2gAMAwEAAhADEAAAAdKtGtYLQxBBKX//xAAdEAABAwUBAAAAAAAAAAAAAAAFAAIEAQMGERQH/9oACAEBAAEFAg0erx1yPpcr0CyQAGA3vSB/M/NZe//EABkRAAIDAQAAAAAAAAAAAAAAAAACERJRAf/aAAgBAwEBPwGUrycLLh//xAAZEQABBQAAAAAAAAAAAAAAAAAAIYGRodH/2gAIAQIBAT8BViL0/8QAJxAAAQMCBAUFAAAAAAAAAAAAAQIDBAARBRIUQRATISIxQ1FhcqH/2gAIAQEABj8CbVb1HvxfDxTKp+GyJbpcmdENRijq72nM48lRUNrpIHzUqLCwAqEhRPPlyWWnmhbKEsaOKjlpH2Kr+VmhlwzDAAAO/XuqNt1L1ybk72SkewFf/8QAHhABAAEEAgMAAAAAAAAAAAAAAREAITFBUWGBkaH/2gAIAQEAAT8h4wD4VOCwuLkvjdcD9NBfyt3AoYmQ9CkPvj3OxTqkPUxCFgGfCkTduUp0q//aAAwDAQACAAMAAAAQKN//xAAdEQACAQQDAAAAAAAAAAAAAAABESExQXHwAGHh/9oACAEDAQE/EESAUsTRWAU+82HHWdr/AP/EAB4RAQEAAAYDAAAAAAAAAAAAAAERACExQVFhodHw/9oACAECAQE/ECFaU6JRk2uL18Ht44z/AP/EAB4QAQEAAgICAwAAAAAAAAAAAAERACFBUTFhgaHh/9oACAEBAAE/EBUm1TsVZ+z4xWBiBBOAq9NDKHnWCAqPTH0TN85+dNI4y4RyB3sQACE2RqJPAQjjj3XjqFqBj//Z"},"images":{"fallback":{"src":"/static/5d3b9180a9db8430e13b85725bd35522/5686d/main.jpg","srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/56262/main.jpg 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/f4b7b/main.jpg 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/16674/main.jpg 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/5686d/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/04d0f/main.avif 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/444d4/main.avif 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/0586b/main.avif 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/d2023/main.avif 1920w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/5d3b9180a9db8430e13b85725bd35522/2bcfc/main.webp 750w,\n/static/5d3b9180a9db8430e13b85725bd35522/5c9b7/main.webp 1080w,\n/static/5d3b9180a9db8430e13b85725bd35522/58a7c/main.webp 1366w,\n/static/5d3b9180a9db8430e13b85725bd35522/abb52/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.7140625}}}},"excerpt":"요약 setter…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/javascript/getter-setter/"}}},{"node":{"frontmatter":{"title":"JavaScript의 얕은 복사와 깊은 복사","date":"2023-02-08","tags":["JavaScript"],"draft":false,"excerpt":"JavaScript의 얕은 복사와 깊은 복사로 알아보는 객체의 특성. (feat. React, Vue.js)","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAQCAYAAAAWGF8bAAAACXBIWXMAABYlAAAWJQFJUiTwAAACnUlEQVR42p2Uy09TQRSH/Qd04eMfENwoFumDCqEtlBYaIprWgEIUA7SNTXShCxMTVy6JykJXPlCRBUsiCzBxISISMDxCQS0Jii9CEMpL+qD33s+5t1ioIhpOcnImc85885tzZ+4OtmuKkvTfbMe2QGr4MgU/Vtbm/gOobLJ7GnBiEpZXiC4uEZudS+U2BcqJhJZUJAlFljcHvuxFmQsT7egg3tySXLNRoapIcwFQEd/GxlgOh7XTyGIulVddrV+JoMTiKO1tKE+aYGYmHagtEopUm+h8xsDefQyerSGizqk51VXQ6mqqTvk4ifS2G3l6BOXDxJ8KVYvEYwwXWPi+ew/jO3cx0vSQRDSWhMTjsLSsbZAsjsHUqFDQC/ML6cDGxkbq6uvx19ZStT+DixmZXBAxYLFRe7KCK14/12q9XPb58Xu9nA8E8Pu93Ll6k5bmUUJDX9eB0WgUt9uNyWTCarVhNJpwmfNwlZXhsFg5la3HlV+Aw1ZIqd6I4bAOu8OBUX8Ed2Udn+YVEpK8DozFYlRVVWEwGMjPyyc3O5sivR6nANsNRiw6HQ6zGacplyJRk2s0YBFt0esNnKupQZISqbalFHo8HqHMSEmJE7urFLsaHXaOFlrI0mdjzjdT7Cqh0GbBKdQ5nU5ycnKEkGoSCSkdqFpDQwOnq6upKD9OeeYB3FYrlcfKKRPj0oNZuItLKDukwyPy7hPl+Hw+7VRq7zd+1LSLvSr60Peig/bAGfpbH/N+qIenl3x03b9BsKeNrkfX6eq8xViwew0i//0t/+pD6N1r+vvvMdh3lzevbjMw8IDgcDOhYCuh8ed8nhwRtyeuKZJlSbu/W/4cJKFyMTzHQniahfkZMZ4VcZFIJP7vd74ZcKti7X0r8pbAn9ryNaEySJ7mAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/c0455e771b38f35341c36082f8b7c15c/492b5/main.png","srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/71312/main.png 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/5feb6/main.png 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/492b5/main.png 1160w","sizes":"100vw"},"sources":[{"srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/b57fe/main.avif 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/62df4/main.avif 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/7aee1/main.avif 1160w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/c0455e771b38f35341c36082f8b7c15c/5d2c1/main.webp 750w,\n/static/c0455e771b38f35341c36082f8b7c15c/0bcd6/main.webp 1080w,\n/static/c0455e771b38f35341c36082f8b7c15c/9ca95/main.webp 1160w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.789655172413793}}}},"excerpt":"요약 얕은 복사란, 참조형 타입의 값이 바로 아래 단계의 값만 복사하는 방법이다. 깊은 복사란, 참조형 타입 안의 모든 참조가 끊어지는 방법이다. React의 경우 얕은 복사를 통해 state값을 비교하고, 변경 되었다면 리랜더링 한다. Vue…","fields":{"readingTime":{"text":"13 min read"},"layout":"post","slug":"/javascript/shallo-copy-and-deep-copy/"}}},{"node":{"frontmatter":{"title":"nvm을 사용해 프로젝트별로 Node.js 버전 다르게 사용하기","date":"2022-04-10T12:13:47.149Z","tags":["Tool","Node.js"],"draft":false,"excerpt":"NVM을 사용해 프로젝트 별로 Node.js 버전 지정을 자동화 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/webp;base64,UklGRtoAAABXRUJQVlA4IM4AAAAwBACdASoUAAgAAAAAJQBdjkAZwBtIGUAeSN/YOv/IoH/w5p6lHd0QTgAA/v//ZyH/66zx//x72KQuDXwT2QKTf+n//27H/yNP9///xPj8F+htBKaI2xLn7VJOy4231//L7+x6//nQeaq/6pm9zGTvi2eFIsIOMc4unw/WW6Ya5c6qf2Fhmnnq5/FdtKP2oZwEj/9vf+9Z/2HRLOBl8///w8/irP1GbK8l4BudWc8HcamhbFwmnr5597nw534+O8mwMHmNv324Jg7PcoAAAA=="},"images":{"fallback":{"src":"/static/c7934c26406e2c570808f63f8ceaa552/7592a/main.webp","srcSet":"/static/c7934c26406e2c570808f63f8ceaa552/1e0c8/main.webp 750w,\n/static/c7934c26406e2c570808f63f8ceaa552/7592a/main.webp 1000w","sizes":"100vw"},"sources":[{"srcSet":"/static/c7934c26406e2c570808f63f8ceaa552/7c2eb/main.avif 750w,\n/static/c7934c26406e2c570808f63f8ceaa552/588e1/main.avif 1000w","type":"image/avif","sizes":"100vw"}]},"width":1,"height":0.42}}}},"excerpt":"nvm이란, Node Version Manager로, Node.js의 버전을 관리하는 도구다. 시스템에 여러 개의 Node.js를 설치하고 사용할 버전을 쉽게 전환할 수 있도록 도와주는 유틸이다. 이는 쉘(sh, dash, ksh, zsh, bash…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/node/setting-npm-differently-for-each-project/"}}},{"node":{"frontmatter":{"title":"PDF 페이지 CSS로 안전하게 작성하기","date":"2022-04-02T12:13:47.149Z","tags":["CSS","HTML","PDF"],"draft":false,"excerpt":"웹을 개발하다 보면, PDF로 문서를 사용자에게 제공하는 기능을 구현해야 할 때가 있다. 다른 개발자분들이 헤매지 않을 수 있도록 정리해보았다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAABKklEQVR42pWT0U7CMBSGu3nFg+iNS9DoAxB9ARIeghm9dO+i0QteQLxAJJAt8CgwE2AjoHZAu0Dy2xYDi+vidvHnpKfnfGn/0xLOObRiDHyzQQyktd3u9jV9JBMmmlgQgPZ6oN3uQWIt8zwDSrJOJpvG5TJGhMA3TPjEUFGux2fnO6io+wtNA9drda3I8zAUzSPDUJC9TFPlo/5A1fHV6h+gKJCF360WJqcWFrd3CK+u8eU4mF5cYmHbmByfgHY6BYEvTcxqNTDXxfLpGZ/3DqKHR7C3NqaWBdp+LwhsvmJWrSpoUKlg2Whgbt9gXq8LPwmo6+UE/npIEx76Qh+lkvDv6ODhIK+HminvByPisPCUk+8wDMU0+ynJfP53mITGsfanyLy0RvdTfgD4wgAkBeu5twAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/39ee9e2452b5c68830fa2ebb9eec0967/b5380/main.png","srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/5b584/main.png 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/c1f05/main.png 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/b5380/main.png 1200w","sizes":"100vw"},"sources":[{"srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/4814e/main.avif 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/acf79/main.avif 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/30577/main.avif 1200w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/39ee9e2452b5c68830fa2ebb9eec0967/73e0d/main.webp 750w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/9fede/main.webp 1080w,\n/static/39ee9e2452b5c68830fa2ebb9eec0967/81547/main.webp 1200w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"웹을 개발하다 보면, PDF…","fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/html/securely-create-a-pdf-page-with-css/"}}},{"node":{"frontmatter":{"title":"Tripllo 삭제 및 일상 회고","date":"2021-12-04T15:13:47.149Z","tags":["Tripllo 제작기","Diary"],"draft":false,"excerpt":"정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif 파일도 모두 백업해두었다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAAsTAAALEwEAmpwYAAABmElEQVR42p2T607CQBCFff8n8Qn8I2qMxgtaFLGUdun2Lrbd0gu1RQocp0skxMQITnLS2d3p156Z7BF2Yr0CnuwBLgd9XD8bJB0K89EjPYycre41Gy9mgOVqhZ9xtLtoz0+UK1z0+9B0Do1xDA0Ttj9BXtYoygpBnOH0cYTboYVm+SdwjTvVhaL7+JzXmNc16qqifL6tKao5OoqO+6G9H/BG5dJW+P4Oz/MQhiHtN5uWJMfIomucPXsE5PsCLQmcTqcSlqYpFovFpqDWkWc2Oj2TgNZhwKZpUJYlJhPqX57L9T8tb4B1XUEIAcMw4Lou/CCgD8xoOBXOegf28FF3wRiD7/sSGkWRtC/iGGlREtA4HGjoOlRVBecclmWBjcdwbBtJPpPAu0Mst0BNG0JRFJimKeU4DiyCT+IEF0+MgHsO5Vb20JV9a8W5JZ+MjSW4tXxOwP0sr9fojjy6asF2L00z+jsXdCRjRlNugV1y8dvVE99aLleiZ7hSSVEKkZUiTDLxFiUipjwpPiifik53ILqvpqzffb/VF0Se2AeYKr/nAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/688b437d9037a2279635c487fefa0aad/a030c/delete1.png","srcSet":"/static/688b437d9037a2279635c487fefa0aad/d734b/delete1.png 750w,\n/static/688b437d9037a2279635c487fefa0aad/a030c/delete1.png 877w","sizes":"100vw"},"sources":[{"srcSet":"/static/688b437d9037a2279635c487fefa0aad/c0126/delete1.avif 750w,\n/static/688b437d9037a2279635c487fefa0aad/fd774/delete1.avif 877w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/688b437d9037a2279635c487fefa0aad/59596/delete1.webp 750w,\n/static/688b437d9037a2279635c487fefa0aad/8026f/delete1.webp 877w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6259977194982896}}}},"excerpt":"3주 전에, 정들었던 Tripllo 어플리케이션을 삭제했다. AWS EC2, S3, RDB를 내렸다. 배포되어있는 도메인도. 씁쓸하면서 이상한 기분이었다. RDB 생성 script를 백업하고, 소개 페이지에 올려둔 gif…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/tripllo/tripllo-delete/"}}},{"node":{"frontmatter":{"title":"vue-meta와 Meta tag","date":"2021-05-30T20:13:47.149Z","tags":["Vue.js","HTML","SEO"],"draft":false,"excerpt":"Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAYCBQn/xAAVAQEBAAAAAAAAAAAAAAAAAAACA//aAAwDAQACEAMQAAAB34VL1eUnMiGv/8QAHBAAAgICAwAAAAAAAAAAAAAAAgMBBAASBRMx/9oACAEBAAEFAiHYeORaBmWZnRK+pkef/8QAGxEBAAEFAQAAAAAAAAAAAAAAAQIQIUFRkaH/2gAIAQMBAT8BkDIde5ONyn//xAAYEQEAAwEAAAAAAAAAAAAAAAABEBFxwf/aAAgBAgEBPwELN5H/xAAhEAACAQQCAwEBAAAAAAAAAAABAgMABBEhEjETMlFBYv/aAAgBAQAGPwJl2OQIyDgjPwjYqZrl7giNvFCJZOSsnfkADnPfs+X/AK1haKg4DqwJBZXGu0dWUqfhGx+UJFluWYRYxNd3U0Z12YpJShfXvjlQr//EABsQAQEAAwADAAAAAAAAAAAAAAERACExEFGR/9oACAEBAAE/ISZQqqZKgQ6IjiCsSYLArSJIQU+MNAB1DEE9eoihM4ybUtOJg3BsduKp7B+mf//aAAwDAQACAAMAAAAQDM//xAAaEQEBAAIDAAAAAAAAAAAAAAARAQAhMUFh/9oACAEDAQE/EL3Usl0bFnbz0XWc5//EABoRAAICAwAAAAAAAAAAAAAAAAERITEQUWH/2gAIAQIBAT8QORKijYG2FPCxj//EABoQAQEAAgMAAAAAAAAAAAAAAAERAEEQIWH/2gAIAQEAAT8QZjABCO8nBCEcMrCgOhRQ11R4G4JRRwO6L3coMOi14aBpEtYhrMyrSygsqs72r7n/2Q=="},"images":{"fallback":{"src":"/static/41787407cbf03fd6193412aa3138ab5a/ce8f8/main.jpg","srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/ce8f8/main.jpg 613w","sizes":"100vw"},"sources":[{"srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/289cb/main.avif 613w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/41787407cbf03fd6193412aa3138ab5a/4bf02/main.webp 613w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6394779771615008}}}},"excerpt":"Semantic-Tag와 함께 SEO 향상을 위해 meta tag를 프로젝트에 적용하면서 meta tag의 역할과 기능, 그리고 Vue.js에서는 meta tag를 동적으로 어떻게 변화시킬 수 있는지 알아보자. Meta tag? 서비스 기획 -> UI, UX 상세 설계 -> GUI…","fields":{"readingTime":{"text":"6 min read"},"layout":"post","slug":"/tripllo/(2)mysql-design-spring-boot/"}}},{"node":{"frontmatter":{"title":"(1) 제작동기","date":"2021-02-03T10:03:47.149Z","tags":["Tripllo 제작기"],"draft":false,"excerpt":"Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/4 정도 만들어진 상태로 배포되어 있다. 어플을 만들면서 다음번에 같은 문제를 만났을 때 참고할 만한 자료를 남겨두어야지 생각만 하다가 지금부터라도 남겨두어야겠다 싶어 제작기를 적으려고 한다.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAPCAYAAADkmO9VAAAACXBIWXMAAAsTAAALEwEAmpwYAAACHklEQVR42o2TPWzTUBSFOyHEyIBEBzbEjxgoEiCEkFDF3AkWBGJHCLFVgg11QiITAwszKwOwdGkFaoS6lKJCfyAkKY6dhDT2s/3+ncN9L2lhIbGl4yfbz5/Pvfd4iuUc260A9UaIH902lDJQxiLq7GGnFiCklQuNNJcQUkNpO1ZThR2gsvwGVx4/xIdgEzDwQAcIot9IMw6W5oiTDFIqWDMBaKRFjXXwfO0tjC2Qc+XXJOWoketUWC/mxA3iXEOoMcAsF75MrQ2EUFTeEMgIuLHVwGazizZTiBKJdqIQxhK5dPv/AxRUhnOlZIGMC0jXw9FDB2Ush6UPeJnhOrZkpTS4zhCxJjkzvvGaXvwVdvFtu4FuL/HXbrMcaQLQ4P3WK7yoPsJ6+BEFDUVS+W6yzaCDrwRttffQd0P5x/1Y4Ov1Z1hYuoNq8x1gQU3/28fvPwMkjJPLAQFtOWAvi/AlXIHQnKIxdOHKTDywhZAcuj5rUwZIJ1sUcMf+Cw6W0vR3yF3U7VMWBXiJUHugi0nMMlJKjnLfJxeJnO67Ut1Ui2LgW1AKOP+0gmNnr+HEzA2vldXP3m1jt005rKPXT71iik8p4N378zh68hKuz93GoelzWFyqeqADuNh0ejEy+g2dSgHvPXiCI9OncOHyRRw+fhqLy5880A2kvhuNyh4cZHEicKHyEmeuzuH87C3MzN7E6trGgcNW1PM9lSVA+8A/pUlh2d91KpcAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e4152/main.png","srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/17a2a/main.png 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/55283/main.png 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e4152/main.png 1107w","sizes":"100vw"},"sources":[{"srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/676a5/main.avif 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e198f/main.avif 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/e7002/main.avif 1107w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/3c28e/main.webp 750w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/d475f/main.webp 1080w,\n/static/bf24ba2ee5132b0ee0bdfdda2b735e7d/b6a06/main.webp 1107w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.7262872628726287}}}},"excerpt":"Trello 어플리케이션을 만들기 시작한 지 벌써 2달이 조금 안 되었다. 하루에 10시간씩 꼬박 시간을 들여가며 만드는 시간이 조급하면서도 즐거웠다. 현재 어플 상태는 3/…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/tripllo/(1)production-motive/"}}},{"node":{"frontmatter":{"title":"오라클 CHR, ASCII 함수 사용법","date":"2020-06-12","tags":["Oracle"],"draft":false,"excerpt":"CHR(), ASCII() 함수 사용법.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"정의 : 아스키코드값 얻기(숫자) : CHR값 얻기(문자) 이렇게만 적어놓으면 뭐가뭔지 잘 모를테니, 문자로 아스키코드값과 아스키코드로 문자열 값을 얻는 쿼리문을 한번 보자. 결과는, ASCII(‘A’) ASCII(‘Z’) ASCII(‘a…","fields":{"readingTime":{"text":"2 min read"},"layout":"post","slug":"/oracle/CHR-ASCII/"}}},{"node":{"frontmatter":{"title":"오라클 테이블 스페이스 조작","date":"2020-06-11","tags":["Oracle"],"draft":false,"excerpt":"Local Oracle 사용시 용량에 문제가 생기면 이 방법을 사용하자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"이동욱님이 쓰신 책을 다 떼고, SQL을 공부하기 위해 DBlan에서 나온 SQL BOOSTER라는 책을 샀다. 쿼리문을 잘 다루는 백엔드 개발자가 되기 위해 SQL…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/oracle/table-space/"}}},{"node":{"frontmatter":{"title":"ORACLE 계정관련 명령어","date":"2020-06-10","tags":["Oracle"],"draft":false,"excerpt":"ORACLE 계정관련 명령어로 테이블 조작을 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAkFBgj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAcI/9oADAMBAAIQAxAAAAHLMEvKqz7ZTHxfARL/xAAaEAABBQEAAAAAAAAAAAAAAAADAQIEBQYR/9oACAEBAAEFAh3uCRlnociGwuNTiI8thCEH1euOr1//xAAhEQACAgEEAgMAAAAAAAAAAAADBAECBQYREhMACBQhIv/aAAgBAwEBPwHKe0+pArLSnj2gGIfFM1ZrnG5HAV5xruQRso0N0RKuBtdGCbBkAi99Ow0kjwvtTrypSQnGHhXsv8eGwZNpmA8t6Qdiz0SYkV2ixONeU/fCkfmP/8QAHxEAAgMAAQUBAAAAAAAAAAAAAQIDERITAAQFBiFR/9oACAECAQE/AY/RuzLtuSJ1xMuT2kYOpFkSGTaGNgY2qQi20y5+LnoejeJobabdDfHwomvl5TiOVu6Fmv09f//EACcQAAMAAQIEBQUAAAAAAAAAAAECAwQREgAFEyEUIjFRcSNBYZHw/9oACAEBAAY/ApyfxZfJx1ti2maIiwvux8dnNMhp1ymzNobb0k2Bh4UHuOV4GFO/T5k+XDKyb5C1yOW5M0nPFEo41jPIjTI16wukqKznbTYmnAhhtmlZSWd983s4ykZ0sHdKrPdqo7TG0fOvGL9RlMp2CMCewk4qoHt521Hse478a/f11/Prr++NzLqf4n5JJJJ9STqeP//EABsQAQADAQEBAQAAAAAAAAAAAAERITEAQWFx/9oACAEBAAE/IXjLYKJdyeSNO5rn4y9RSphID2vBkKuzDEpoHGnqgDtSAE2yRSMybf6W02dfvRJIFy+2PqJJQRWe/9oADAMBAAIAAwAAABAPH//EABYRAQEBAAAAAAAAAAAAAAAAAAERAP/aAAgBAwEBPxAX8D5jELXQ4wmVFzKtPjjSg1//xAAVEQEBAAAAAAAAAAAAAAAAAAABEf/aAAgBAgEBPxArOsbwS85ULKSGO1VV4uVoKoKKNf/EABkQAQEBAQEBAAAAAAAAAAAAAAERIQAxQf/aAAgBAQABPxAlY7np9Rjzk+/8Q3tFqI1XPiDVimjICXxAOhNRLO8owCemmQybC7/Rrwqqat43RVErTEol005f/9k="},"images":{"fallback":{"src":"/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg","srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/7284f/oracle.jpg 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/39611/oracle.jpg 768w","sizes":"100vw"},"sources":[{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/b0356/oracle.avif 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/f1c79/oracle.avif 768w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/81d8014c53e209d05ed5596eb1b93203/57584/oracle.webp 750w,\n/static/81d8014c53e209d05ed5596eb1b93203/588ff/oracle.webp 768w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"표시가 붙은 녀석들은 SQL PLUS에서 사용하는 명령어가 아니라 그냥 CMD 창에서 치는 명령어들이다. 데이터를 이관할 때, ORACLE 계정을 새로 만들어야 할 때, 유용하게 사용되는 명령어들이다. 1. 계정삭제 혹은 후에 2. 계정생성…","fields":{"readingTime":{"text":"1 min read"},"layout":"post","slug":"/oracle/계정관련-명령어/"}}},{"node":{"frontmatter":{"title":"Spring에서의 MediaType","date":"2020-05-27","tags":["SpringBoot","MediaType"],"draft":false,"excerpt":"Spring MVC에서 MediaType 매핑에 대해서 알아보고 테스트 해보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVR42m1T32vTUBROO4dOUfDNMQWfRFQULIzhltwk3cAHn4S+CNKhWHW5SbOkFXyQO6YTUUGrBadOEEWQgmhy0x/bukYFwYfBQNA96F+ggogPsqf4JVmdWi8cTnLu+fGdc74rCPFJCJ0n8bcOYh3E/7nFXHemkumKTKEttifWgpmQZAFLRk5rDsJ4ZaAndzfVzRhL2rMjm9oBhqekzLrYG8ZE4pN1OTe1MbrUXPGgzqUl6pL30Mu6K73Va2T76cpAH3WlW4YrHdM9MqVxMmF40pjOybTukgJkCvabRpWcoaHdJdejhOasMgf5jotGvkqa+F7J15WHuWdiL+VIyEkZcsl6nd5lL6hLVlPVIKMFP92ym+qeQivtIOYKAO0WUOG42VC+AQlD5ZLuybc1T5qE7YfB5azmiCYKTZt18hT3ExCTVuVB6pFhdHN1nKt91JFPUkcqU05eCoUF1YfTh6KfLqP6su2nP6H6ZSD9Cv0ommMTQVwS/1zK6gJ+LwEJjyLPecGoyVm0F2jPRVNzpXkgrqC9C/m6vIJZWkBunPWGto55ZJvpKHuxtB7DGdpP+eCBEO0/ReJjzikta179SR3xAeRJ0R8O0PKM/WZkn91SHYzhnuHJ9/VqNJI71JVvIGam+EottWmTqQhdLBCSMVwu9mMeH7HNz9BfUPmd1RB35OtkJ1A+Nrh0DgMv4nsSczqF9q9hhqPwvajX+rf8D2UHsYMgJnLWJxsiHoJnbPFIxLMTLw5tDhPopcPrQw52PIk2OduEDsnNWAw/bCdsJWqJCavEDxKhfxB0vrBf2Ion9AeQW1wAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png","srcSet":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/8315cb308b890c7087edfc088043f572/1260c/springboot.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/8315cb308b890c7087edfc088043f572/22c65/springboot.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"계속 JUnit에 대해서 공부하고 있는데 속성으로 MediaType이 등장했다. 궁금증이 생겨 MediaType에 대해서 조금 알아보았다. MediaType이란? wiki의 말에 따르면, 미디어타입(media type…","fields":{"readingTime":{"text":"3 min read"},"layout":"post","slug":"/spring/MediaType/"}}},{"node":{"frontmatter":{"title":"JUnit(2) - Mockito","date":"2020-05-25","tags":["SpringBoot","JUnit"],"draft":false,"excerpt":"Mockito 프레임워크를 통해 Mock 테스트를 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMABhqAAAYagAH+TSlKAAAByElEQVR42mNgoBwwUsUA12IlsehG44qClmhJbm4lMaAQK1mG1dfXM4EY8Y22fbtPrv//7Mmrk9NmLDowbdEiMbwu+P+fgRGEQWyYISCwatUqZhA9Y8XcxE9fv/6/cev+/5Nnr//6//+/NtyE+np7lspVNqIVC52F6+fbc4DY9avseUC4ZqGdZu0SB+vQUBlOVlZWIw4ODnuQntLu1Ky+jaX/p2zu+Hf46sFvrz5+VIUbWLvU0bh6sV1V1SL7yurFtvHVi2yjqxbZJlQvtEmtX2pt07TaaWZKo4E/UGk+CxtLMZD29Ylz7y+Ylvi/cGLs/8M3tz8FupAXYeACR+PahQ72NUvsfeqW2MdWL3LMrFlsn1K9yCG7ep6rU/0Kh7L4WsNgoNIwLi72RCAdY+/qWrnt1MG/Dz+/+f/w7btVkGD6D4nxiYvr+aYtrRCctqhebNrSaYKdM9JMeuZVy7bNLlRpmRVvMGH2BPGOCXlyubkpMlFRiUoeHn5art7eOvfffiy+/ertgvP3nxhADYSENchkGN6//z8LSOLMmTOsIAySP7bjmNC2bdvYgeJs+/fv5wgNDWUGspnhLiIlsSJpQqbBGBTj6AYDAGU710j0CbAkAAAAAElFTkSuQmCC"},"images":{"fallback":{"src":"/static/494e2ef858fa149461fcb71d317a1049/ed3fb/mockito.png","srcSet":"/static/494e2ef858fa149461fcb71d317a1049/e7dcc/mockito.png 750w,\n/static/494e2ef858fa149461fcb71d317a1049/ed3fb/mockito.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/494e2ef858fa149461fcb71d317a1049/06049/mockito.avif 750w,\n/static/494e2ef858fa149461fcb71d317a1049/c1b27/mockito.avif 800w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/494e2ef858fa149461fcb71d317a1049/ee7ce/mockito.webp 750w,\n/static/494e2ef858fa149461fcb71d317a1049/e7773/mockito.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5}}}},"excerpt":"이전 포스팅에서는 Assertion 객체를 사용해, 테스트 코드의 return 값을 검증했다. 단순히 return 되는 값만 검증한 것인데, 만약 return 값이 없는 테스트를 하려면 어떻게 해야할까? 즉, void…","fields":{"readingTime":{"text":"5 min read"},"layout":"post","slug":"/spring/JUnit(2)Mockito/"}}},{"node":{"frontmatter":{"title":"Github Blog에 카카오톡 공유버튼 만들기","date":"2020-05-22T09:03:47.149Z","tags":["Blog"],"draft":false,"excerpt":"Jekyll로 만든 Github 블로그에 카톡 공유버튼을 만들어보자!","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsTAAALEwEAmpwYAAACjUlEQVR42n2S3UtTYRzHDxSs/yDDCV103V1BFERE0UUXvQgW5oV0MRsJLXyBkWggERZh4KKEglw4pEZYbIgGw+VrKnO+bZ6lObez7WznOWfbOWda23m+PZuQXURf+PCF38PzuXieH2dtaalqa3tsttvs1RaLpdpms/3Bbi+3hbX9v3R2dpqtVmsVx3EHuNji8qwSC2gR8j2Ty+WJLMtEVhRSTjpNiEgKRMxkiJhKEVEU/0WGRY9Go9+Y8BAnSySyvb2FpdCqMbcQQCjMg+d5rEe2UMjHUODfoqRkUA6lFLTc2I/BUm5d19eZ0MSl06lIeG0VK8GAMTczBT4cwvJSEMGVMPTNaejDtTDkxN5tauDvlMWlfWG4IsxreiTPBnEdRmKHQi0COe0nNuMy1rdkRBM7UPRfWEvnMR9XEEhkkVR3gaIIWtyEUdpgQgm6lt0Tzv7IRRo8Om5/loy6DxK6vqpo7/mEs7deor51EOfrX6DbPQ+uw4OTDj8OPvCgdnAeSDcjvXAa/Pg5A6kr0MgsE14ycf4Nhb/2UUP/Qq5k9crU9iVL73S8p3X33tFXQ9P01NVe2jowSbn2YfpwZJnWPBqlF/onKUgjHRs8QZ90nSlBvAg17Q9x3HMTtyiokdYJ4O6YbjR6dTiCRTx9PY7LTQO42TKEhvsuOEbXcLR3AscdUzjcM45mTwjIdqEUuw4jecNAvgm6EmCfcszESZI8kcntZJKKFksoqqCoBUFW8kI8KQlCkggJkQg5VRO2paywKSoVpJwq7BaIUFAFQcsnYrs62y8i+Stv2NfXVzXictX43E5zGbeTwXrG563gYzjZbMbrNvM+tznI2svO+51uhq/CG9dITXf3syPlxf4NkN9Kkm8uxCEAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/122e747ed0f9d7367c71f42c3f5a94fa/81543/main.png","srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/81543/main.png 605w","sizes":"100vw"},"sources":[{"srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/5f09e/main.avif 605w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/122e747ed0f9d7367c71f42c3f5a94fa/5fc57/main.webp 605w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.48099173553719005}}}},"excerpt":"개발 공부를 하다 공부한 것을 OneNote에 기록해두었는데, 항상 구글링 할때마다 개발자들이 github.io 로 된 블로그에서 도움을 많이 얻어 나도 언젠간 공부한 것들을 내 github 블로그에 포스팅 해야지 싶어서 github…","fields":{"readingTime":{"text":"8 min read"},"layout":"post","slug":"/blog/jekyll-kakao-share-button/"}}},{"node":{"frontmatter":{"title":"JUnit(1) - 개념","date":"2020-05-21","tags":["SpringBoot","JUnit"],"draft":false,"excerpt":"SpringBoot에서 JUnit의 개념짚기.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAAsTAAALEwEAmpwYAAACXUlEQVR42m1T32vTUBROO4dOUfDNMQWfRFQULIzhltwk3cAHn4S+CNKhWHW5SbOkFXyQO6YTUUGrBadOEEWQgmhy0x/bukYFwYfBQNA96F+ggogPsqf4JVmdWi8cTnLu+fGdc74rCPFJCJ0n8bcOYh3E/7nFXHemkumKTKEttifWgpmQZAFLRk5rDsJ4ZaAndzfVzRhL2rMjm9oBhqekzLrYG8ZE4pN1OTe1MbrUXPGgzqUl6pL30Mu6K73Va2T76cpAH3WlW4YrHdM9MqVxMmF40pjOybTukgJkCvabRpWcoaHdJdejhOasMgf5jotGvkqa+F7J15WHuWdiL+VIyEkZcsl6nd5lL6hLVlPVIKMFP92ym+qeQivtIOYKAO0WUOG42VC+AQlD5ZLuybc1T5qE7YfB5azmiCYKTZt18hT3ExCTVuVB6pFhdHN1nKt91JFPUkcqU05eCoUF1YfTh6KfLqP6su2nP6H6ZSD9Cv0ommMTQVwS/1zK6gJ+LwEJjyLPecGoyVm0F2jPRVNzpXkgrqC9C/m6vIJZWkBunPWGto55ZJvpKHuxtB7DGdpP+eCBEO0/ReJjzikta179SR3xAeRJ0R8O0PKM/WZkn91SHYzhnuHJ9/VqNJI71JVvIGam+EottWmTqQhdLBCSMVwu9mMeH7HNz9BfUPmd1RB35OtkJ1A+Nrh0DgMv4nsSczqF9q9hhqPwvajX+rf8D2UHsYMgJnLWJxsiHoJnbPFIxLMTLw5tDhPopcPrQw52PIk2OduEDsnNWAw/bCdsJWqJCavEDxKhfxB0vrBf2Ion9AeQW1wAAAAASUVORK5CYII="},"images":{"fallback":{"src":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png","srcSet":"/static/8315cb308b890c7087edfc088043f572/86184/springboot.png 600w","sizes":"100vw"},"sources":[{"srcSet":"/static/8315cb308b890c7087edfc088043f572/1260c/springboot.avif 600w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/8315cb308b890c7087edfc088043f572/22c65/springboot.webp 600w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.525}}}},"excerpt":"Web 프로젝트를 하다보면 오류는 당연히 만나는 것이고 그 때마다 을 찍어보거나 로 log를 찍는일이 대부분이었다. 또 log를 확인하기 위해 WAS를 올렸다 내렸다하는 번거로움까지. 하지만 WAS…","fields":{"readingTime":{"text":"4 min read"},"layout":"post","slug":"/spring/JUnit(1)motive/"}}},{"node":{"frontmatter":{"title":"Java 다형적 변수, 형변환","date":"2019-07-19","tags":["Java"],"draft":false,"excerpt":"Java의 다형성을 통해 다형적 변수와 형변환에 대해서 알아보자.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAgMAAAAAAAAAAAAAAAAAAAUGBwn/xAAWAQEBAQAAAAAAAAAAAAAAAAAGAgP/2gAMAwEAAhADEAAAAd7ou9V5WrKZDir/xAAaEAADAQEBAQAAAAAAAAAAAAAAAgQFAxIV/9oACAEBAAEFAlJb07H01Y9C58vM2L6pND//xAAgEQACAQQCAwEAAAAAAAAAAAABAgMEERIhEyIABkEy/9oACAEDAQE/ARbB+9mOICcKvkL3J5TIGiIsPyj5gkEr9p/UqipghnSpGM0aSLpR1cBhptjR+78//8QAHxEAAgICAgMBAAAAAAAAAAAAAQIDERMhBBIABkEi/9oACAECAQE/AW7ZEpLUdiXzMnU1QGERsswNnbOmMgEBr1P7RDx5pYG436ido2ssdoaO1NfPmvP/xAAoEAACAAUCBQQDAAAAAAAAAAABAgMREhMhAAQiMTJBUVJxgZGhsfD/2gAIAQEABj8Cn+fb41ujHYIq7hxCnKGbahKVUVFopMme4k0cZEukEptNwYc+B4liFcX1osSMHoJmAWVCSDwykTSe/D46g38P3qAqLFEmNDncRmdDQchndsnvy+saj7e5ctkCvpqmA2RnOZHzzkOWv//EABsQAQEBAAIDAAAAAAAAAAAAAAERIQBRMUFh/9oACAEBAAE/IZFWk7drnx3XJc4JPRwNTWtRGO8LV16foeaNPDOIpyElpojU6Awefa+U8pJ9Rl+PWDirvaoWBEUgCgxCBY//2gAMAwEAAgADAAAAEPwv/8QAGREBAAIDAAAAAAAAAAAAAAAAAREhAEFh/9oACAEDAQE/EGZEiAQw7LgAj8BwxQ9B1IA5FG7L/8QAGBEBAQEBAQAAAAAAAAAAAAAAAREhAEH/2gAIAQIBAT8QDiDtZa4ho131HJEhxa21Oq32yZP/xAAaEAEBAQEBAQEAAAAAAAAAAAABEQAhMUFR/9oACAEBAAE/ECyUSweRtASj1AFdZobnXPFOnx0mF95UIThfBEQ8r9idS3uL8EpfwcxdO3GlIcRMkW1HNKYZk64M9Dv/2Q=="},"images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/2a117/java.avif 396w","type":"image/avif","sizes":"100vw"},{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}},"excerpt":"…","fields":{"readingTime":{"text":"2 min read"},"layout":"post","slug":"/java/다형적변수/"}}}]}},"pageContext":{"limit":1000,"skip":0,"numPages":1,"currentPage":1}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file diff --git a/page-data/tags/bundler/page-data.json b/page-data/tags/bundler/page-data.json index 78f4b01d0..ab932868e 100644 --- a/page-data/tags/bundler/page-data.json +++ b/page-data/tags/bundler/page-data.json @@ -1 +1 @@ -{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/bundler/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":2,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","tags":["Bundler","Webpack","Environment"],"date":"2023-04-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"tag":"Bundler"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file +{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/bundler/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":2,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite의 철학에 기반한 방식 import.meta에 대한 이야기","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","tags":["Bundler","Webpack","Environment"],"date":"2023-04-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"tag":"Bundler"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file diff --git a/page-data/tags/environment/page-data.json b/page-data/tags/environment/page-data.json index b3667324c..8121225b7 100644 --- a/page-data/tags/environment/page-data.json +++ b/page-data/tags/environment/page-data.json @@ -1 +1 @@ -{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/environment/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":4,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"excerpt":"프로젝트를 진행하다 보면 하나의 파일에 import 대상이 많아질 때가 있다. import 문이 많으면 어떤 모듈이 import 되었는지 파악하기가 쉽지 않고 지저분해 보인다. 위의 이미지는 Next.js 프로젝트의 파일의 import…","frontmatter":{"title":"ESLint로 import 구문에 규칙 넣기","excerpt":"규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.","tags":["Environment","ESLint"],"date":"2023-09-06","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUGBAj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAgJ/9oADAMBAAIQAxAAAAHvHe+f5P0/BF+Ih//EABoQAQACAwEAAAAAAAAAAAAAAAMCBQABBBL/2gAIAQEAAQUC6GPkWPhM3zri0xvYTrybRVxDH//EAB8RAAICAQQDAAAAAAAAAAAAAAECAwQSAAURFDJBgf/aAAgBAwEBPwG1utZUqNXnLStXJurJE+C2ezPikRwU4dUVizEvzKX4I8QN/X2V+I/Gv//EACERAAICAQQCAwAAAAAAAAAAAAECAwQRAAUGEhMxISJS/9oACAECAQE/AavEdulijhsVN0SbBLXK12jIFYscI1KfxiXqvUhktwDBwQxBOpuEW0ldYPJLCGIjkeWtEzp8YZo/v0JHte7Y/R96/8QAKRAAAgECAwUJAAAAAAAAAAAAAQIDERIABEETMTJRkQUhIiNCU2KBkv/aAAgBAQAGPwLKwy7Ta513SBI0vLGNb3J5KBriiSLf7beCT8Pa3QHHCcZPtBp5LsnFPFHFapj8/ikPqvA7hQ7sUlo4+SKeld31ixXkpWouYtSuguqQvIVoNMf/xAAfEAEAAgIBBQEAAAAAAAAAAAABESEAYVExQXGBseH/2gAIAQEAAT8hOZJ8EwBJsnuWCWkJMbB+tY0N3gl+H7l5NnRrIoCaClVkpuNG7UlcKE5ydvOXQa9keUMArP/aAAwDAQACAAMAAAAQMC//xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMWH/2gAIAQMBAT8Q4O0KU9CJGmAMBgUAWqtWKDO7QfNF/8QAFxEBAQEBAAAAAAAAAAAAAAAAAREhUf/aAAgBAgEBPxBYdg6WI/aaU4gf8yz1NIiqAxf/xAAZEAEBAQEBAQAAAAAAAAAAAAABESExAKH/2gAIAQEAAT8Q0HMw9uc8VKcfFzB1TDpsLF4sQFMk23dfQ95nPAkThPFrXyLQQletTC1yUzDoTQO+UZGmJV7sU1EQB//Z"},"images":{"fallback":{"src":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg","srcSet":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/745053477406742b937cf317c03bd51c/62859/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671874999999999}}}},"fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/environment/putting-rules-into-import-syntax-with-eslint/"}}},{"node":{"excerpt":"TypeScript를 사용해 개발 하는 단계는 크게 3가지로 나눌 수 있다. Lint stage Compile stage Runtime stage Lint stage는 개발자가 코드를 작성하는 시점이다. Compile stage…","frontmatter":{"title":"TypeScript의 기본개념과 환경설정","excerpt":"TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)","tags":["TypeScript","Environment"],"date":"2023-05-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMElEQVR42mP4////v38oiHjAANKMikjTjAaA+v+imvH3H27NNbufm0+/5Tb/rvPcOw5z7px9+g0o+Psv1JR/MBMxnQbS7L/wLkP2aZbiswwFZxiKz2658fHll98/fv/7B1YLpO+8/fnjD8iYX3/+AQ399usvQrP3onsGU25mbHwcsPS+xYxbyy6+33X747bbH1ddfT///Ntll9/3Hn+14cYHIHfllffTTr/ZdPMjxC0gzW4L7ir3Xs/Z8iR+7aO6Pc833/j4/fe/vfc+A/UffPD5xJOvF55/O/X065VX388//7bxxscH739CQgGk2WvhPa66i46z7wCtLdj6dN/dz0BBoH6sYYnu54cffl588R2Irr36DgytTz/+QiMfHGCQMEMgpLTAgCsOiUktDP8pAAA9+2KaOzXrLQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png","srcSet":"/static/e092969a3269e232f50e03e941f3d22f/38824/main.png 750w,\n/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/24bb5/main.webp 750w,\n/static/e092969a3269e232f50e03e941f3d22f/a78a0/main.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5475}}}},"fields":{"readingTime":{"text":"16 min read"},"layout":"post","slug":"/typescript/typescript-env/"}}},{"node":{"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","tags":["Bundler","Webpack","Environment"],"date":"2023-04-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"tag":"Environment"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file +{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/environment/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":4,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite의 철학에 기반한 방식 import.meta에 대한 이야기","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}},{"node":{"excerpt":"프로젝트를 진행하다 보면 하나의 파일에 import 대상이 많아질 때가 있다. import 문이 많으면 어떤 모듈이 import 되었는지 파악하기가 쉽지 않고 지저분해 보인다. 위의 이미지는 Next.js 프로젝트의 파일의 import…","frontmatter":{"title":"ESLint로 import 구문에 규칙 넣기","excerpt":"규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.","tags":["Environment","ESLint"],"date":"2023-09-06","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAUGBAj/xAAXAQADAQAAAAAAAAAAAAAAAAADBAgJ/9oADAMBAAIQAxAAAAHvHe+f5P0/BF+Ih//EABoQAQACAwEAAAAAAAAAAAAAAAMCBQABBBL/2gAIAQEAAQUC6GPkWPhM3zri0xvYTrybRVxDH//EAB8RAAICAQQDAAAAAAAAAAAAAAECAwQSAAURFDJBgf/aAAgBAwEBPwG1utZUqNXnLStXJurJE+C2ezPikRwU4dUVizEvzKX4I8QN/X2V+I/Gv//EACERAAICAQQCAwAAAAAAAAAAAAECAwQRAAUGEhMxISJS/9oACAECAQE/AavEdulijhsVN0SbBLXK12jIFYscI1KfxiXqvUhktwDBwQxBOpuEW0ldYPJLCGIjkeWtEzp8YZo/v0JHte7Y/R96/8QAKRAAAgECAwUJAAAAAAAAAAAAAQIDERIABEETMTJRkQUhIiNCU2KBkv/aAAgBAQAGPwLKwy7Ta513SBI0vLGNb3J5KBriiSLf7beCT8Pa3QHHCcZPtBp5LsnFPFHFapj8/ikPqvA7hQ7sUlo4+SKeld31ixXkpWouYtSuguqQvIVoNMf/xAAfEAEAAgIBBQEAAAAAAAAAAAABESEAYVExQXGBseH/2gAIAQEAAT8hOZJ8EwBJsnuWCWkJMbB+tY0N3gl+H7l5NnRrIoCaClVkpuNG7UlcKE5ydvOXQa9keUMArP/aAAwDAQACAAMAAAAQMC//xAAZEQEBAAMBAAAAAAAAAAAAAAABEQAhMWH/2gAIAQMBAT8Q4O0KU9CJGmAMBgUAWqtWKDO7QfNF/8QAFxEBAQEBAAAAAAAAAAAAAAAAAREhUf/aAAgBAgEBPxBYdg6WI/aaU4gf8yz1NIiqAxf/xAAZEAEBAQEBAQAAAAAAAAAAAAABESExAKH/2gAIAQEAAT8Q0HMw9uc8VKcfFzB1TDpsLF4sQFMk23dfQ95nPAkThPFrXyLQQletTC1yUzDoTQO+UZGmJV7sU1EQB//Z"},"images":{"fallback":{"src":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg","srcSet":"/static/745053477406742b937cf317c03bd51c/e70fc/main.jpg 640w","sizes":"100vw"},"sources":[{"srcSet":"/static/745053477406742b937cf317c03bd51c/62859/main.webp 640w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6671874999999999}}}},"fields":{"readingTime":{"text":"9 min read"},"layout":"post","slug":"/environment/putting-rules-into-import-syntax-with-eslint/"}}},{"node":{"excerpt":"TypeScript를 사용해 개발 하는 단계는 크게 3가지로 나눌 수 있다. Lint stage Compile stage Runtime stage Lint stage는 개발자가 코드를 작성하는 시점이다. Compile stage…","frontmatter":{"title":"TypeScript의 기본개념과 환경설정","excerpt":"TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)","tags":["TypeScript","Environment"],"date":"2023-05-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAIAAADwazoUAAAACXBIWXMAAAsTAAALEwEAmpwYAAABMElEQVR42mP4////v38oiHjAANKMikjTjAaA+v+imvH3H27NNbufm0+/5Tb/rvPcOw5z7px9+g0o+Psv1JR/MBMxnQbS7L/wLkP2aZbiswwFZxiKz2658fHll98/fv/7B1YLpO+8/fnjD8iYX3/+AQ399usvQrP3onsGU25mbHwcsPS+xYxbyy6+33X747bbH1ddfT///Ntll9/3Hn+14cYHIHfllffTTr/ZdPMjxC0gzW4L7ir3Xs/Z8iR+7aO6Pc833/j4/fe/vfc+A/UffPD5xJOvF55/O/X065VX388//7bxxscH739CQgGk2WvhPa66i46z7wCtLdj6dN/dz0BBoH6sYYnu54cffl588R2Irr36DgytTz/+QiMfHGCQMEMgpLTAgCsOiUktDP8pAAA9+2KaOzXrLQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png","srcSet":"/static/e092969a3269e232f50e03e941f3d22f/38824/main.png 750w,\n/static/e092969a3269e232f50e03e941f3d22f/c02d0/main.png 800w","sizes":"100vw"},"sources":[{"srcSet":"/static/e092969a3269e232f50e03e941f3d22f/24bb5/main.webp 750w,\n/static/e092969a3269e232f50e03e941f3d22f/a78a0/main.webp 800w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5475}}}},"fields":{"readingTime":{"text":"16 min read"},"layout":"post","slug":"/typescript/typescript-env/"}}},{"node":{"excerpt":"예전에 간단한 JavaScript를 사용해 페이지를 만들어볼 목적으로 webpack 기반 보일러플레이트를 만든 적이 있다. 유용하게 잘 써먹었지만, webpack을 처음부터 하나 하나 뜯어보며 설정했던 것은 아니다. 사실 요즘은 webpack…","frontmatter":{"title":"Webpack5 JavaScript 보일러플레이트 만들기","excerpt":"모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.","tags":["Bundler","Webpack","Environment"],"date":"2023-04-05","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAIAAAA7N+mxAAAACXBIWXMAAAsTAAALEwEAmpwYAAABOUlEQVR42mPgV83DiVRy+VWygUhALV9AvRhTAQMqPx+BVHIF1Ev4tNoEdNp5lMsFNCtAgmr5ODXzKWfDUKaQdo2YxRyHvAMxk67YZ+8S1m8H6uRTTONXzsbQDDRSrUBYt0FYrwmIxEz7hMwXOBfuj1l4S7/+SOziO86FB3lUq8Vtpwsa1IL15yNrLgCSYmZTJWwWSFjNk/PcIe58OLL/rHblIebwNbrVhyL7znGpVCtFXZVwWsqrmApRz4DwrUqekG6dsFEryGbzfmHzeY4F+xOW3zNtPJq48oFjwQEejRox28lCJs186DZDENC3SlkQPwtqVYuaz7LL3h/Vf8UmbZugTrOAKtDP6fzKWRCd+EM7h1+tkEe9kVejiVMulw+kBxI0OKMKzSBgPAP1ZIM15BOMZ6xG5OOSBQBYuph02N9mfQAAAABJRU5ErkJggg=="},"images":{"fallback":{"src":"/static/398ff7eccce15fa106b9755da8007778/90018/main.png","srcSet":"/static/398ff7eccce15fa106b9755da8007778/f503b/main.png 750w,\n/static/398ff7eccce15fa106b9755da8007778/e4953/main.png 1080w,\n/static/398ff7eccce15fa106b9755da8007778/c2802/main.png 1366w,\n/static/398ff7eccce15fa106b9755da8007778/90018/main.png 1720w","sizes":"100vw"},"sources":[{"srcSet":"/static/398ff7eccce15fa106b9755da8007778/77272/main.webp 750w,\n/static/398ff7eccce15fa106b9755da8007778/317ed/main.webp 1080w,\n/static/398ff7eccce15fa106b9755da8007778/b5c49/main.webp 1366w,\n/static/398ff7eccce15fa106b9755da8007778/e0b55/main.webp 1720w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5232558139534883}}}},"fields":{"readingTime":{"text":"33 min read"},"layout":"post","slug":"/environment/webpack-boilerplate/"}}}]}},"pageContext":{"tag":"Environment"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file diff --git a/page-data/tags/vite/page-data.json b/page-data/tags/vite/page-data.json index 789ac0690..65f7054be 100644 --- a/page-data/tags/vite/page-data.json +++ b/page-data/tags/vite/page-data.json @@ -1 +1 @@ -{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/vite/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}}]}},"pageContext":{"tag":"Vite"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file +{"componentChunkName":"component---src-templates-tags-tsx","path":"/tags/vite/","result":{"data":{"allTagYaml":{"edges":[{"node":{"yamlId":"java","description":"Some of the greatest words ever spoken.","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","backgroundColor":"#f8f8f8","images":{"fallback":{"src":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg","srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/8ba2c/java.jpg 396w","sizes":"100vw"},"sources":[{"srcSet":"/static/a23f2bad7cf7c4db98e32e524cae7667/ed9a5/java.webp 396w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.6666666666666666}}}}}]},"allMarkdownRemark":{"totalCount":1,"edges":[{"node":{"excerpt":"회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. vue-cli는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack…","frontmatter":{"title":"Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)","excerpt":"Vite의 철학에 기반한 방식 import.meta에 대한 이야기","tags":["Bundler","Vite","Environment"],"date":"2024-02-04","image":{"childImageSharp":{"gatsbyImageData":{"layout":"fullWidth","placeholder":{"fallback":"data:image/jpeg;base64,/9j/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wgARCAALABQDASIAAhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAAgDBAUJ/8QAFgEBAQEAAAAAAAAAAAAAAAAAAwAC/9oADAMBAAIQAxAAAAHioxyxxrq2a5D/AP/EAB0QAAICAQUAAAAAAAAAAAAAAAEDAgQFBgcREzP/2gAIAQEAAQUCQEi3uDhNDYSqFiYHsGT6K8eU/wD/xAAcEQADAQACAwAAAAAAAAAAAAABAgMRAAQTMVL/2gAIAQMBAT8Bk80TshpeR7SnOTljkCtko1ET0XdA0ifhzukLnP/EAB4RAAICAQUBAAAAAAAAAAAAAAIDAQQTABESFCJx/9oACAECAQE/ASFZYiKXC2u42KxtgUtFtZ9ZqriZAuwscoWK3pZV7SFtiZjkBbfNf//EACcQAAIBAwMDAwUAAAAAAAAAAAECAwQREhMhMQAFIhRBUQYWoaKx/9oACAEBAAY/AoUqI55aX1MRqY6cRrO1PpDW0YirRCXDMxS+Sl+V36+lftWt7nXVdd22mre41NXUpJHoSM6085Kx40ss5DCOmjAiSKNiweRlxyKHfI3EExy823yi8G+LgDj4A6EO+nqq2HtfQ5/Y/wA46zyJaD06RX3xTInG3BW7HYggdIbsC1ycXdBcsfZSB+ONuB1//8QAGhABAQEAAwEAAAAAAAAAAAAAAREhADFRQf/aAAgBAQABPyEB0QioD06aBvPMkyJr1vEDS1wS+uUffxbVsQFC1s+uJEII0j0vT4HHpEHKJG1IkuGBCBJRfBFZ/wAzABAD/9oADAMBAAIAAwAAABDQ7//EABcRAQADAAAAAAAAAAAAAAAAAAEQESH/2gAIAQMBAT8QD+YHPqFkohgRf//EABsRAAIBBQAAAAAAAAAAAAAAAAERIQAxYdHw/9oACAECAQE/ELOkBMVBFxj+qTRUkZeNcgv/xAAXEAEBAQEAAAAAAAAAAAAAAAABEQAh/9oACAEBAAE/EK8yc0UjoSrqANjQlcA6Uhirylvrj0pCCC29EhbINgwIAAA4ICG6ohgTTj05g49wjVX34qCAT4b/2Q=="},"images":{"fallback":{"src":"/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg","srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/37bba/main.jpg 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/61c72/main.jpg 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/d61e8/main.jpg 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/a764f/main.jpg 1920w","sizes":"100vw"},"sources":[{"srcSet":"/static/3e003894f92a9a0261250e0307b1c3bf/a66aa/main.webp 750w,\n/static/3e003894f92a9a0261250e0307b1c3bf/65dd5/main.webp 1080w,\n/static/3e003894f92a9a0261250e0307b1c3bf/4fad6/main.webp 1366w,\n/static/3e003894f92a9a0261250e0307b1c3bf/c512e/main.webp 1920w","type":"image/webp","sizes":"100vw"}]},"width":1,"height":0.5625}}}},"fields":{"readingTime":{"text":"15 min read"},"layout":"post","slug":"/environment/why-do-you-use-import-meta-in-vite/"}}}]}},"pageContext":{"tag":"Vite"}},"staticQueryHashes":["1661920220"],"slicesMap":{}} \ No newline at end of file diff --git a/rss.xml b/rss.xml index c76fa5a8e..d69a21184 100644 --- a/rss.xml +++ b/rss.xml @@ -1,4 +1,4 @@ -<![CDATA[Pozafly's 블로그]]>https://pozafly.github.ioGatsbyJSSun, 04 Feb 2024 14:43:53 GMT<![CDATA[Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)]]>https://pozafly.github.io/environment/why-do-you-use-import-meta-in-vite/https://pozafly.github.io/environment/why-do-you-use-import-meta-in-vite/Sun, 04 Feb 2024 00:00:00 GMT<p>회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. <a href="https://github.com/vuejs/vue-cli" target="_blank" rel="nofollow">vue-cli</a>는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 내부에 묶여있는 eslint, prettier 등의 도구도 latest 버전과 호환이 되지 않았다.</p> +<![CDATA[Pozafly's 블로그]]>https://pozafly.github.ioGatsbyJSSun, 04 Feb 2024 14:50:42 GMT<![CDATA[Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)]]>https://pozafly.github.io/environment/why-do-you-use-import-meta-in-vite/https://pozafly.github.io/environment/why-do-you-use-import-meta-in-vite/Sun, 04 Feb 2024 00:00:00 GMT<p>회사에서 vue-cli로 만들어진 프로젝트를 Vite로 마이그레이션을 진행 중이다. <a href="https://github.com/vuejs/vue-cli" target="_blank" rel="nofollow">vue-cli</a>는 2년 전부터 maintenance mode(deprecated)에 들어갔고, webpack을 기반으로 만들어졌기 때문에 번들링 및 빌드 할 때 무척 느리다. vue-cli 패키지 내부에는 eslint, prettier가 vue-cli에 맞게 묶여있었는데 최신 버전의 eslint, prettier 버전을 사용하고 싶어도 호환이 되지 않았다. 그래서 vue-cli 대신 번들러를 바꿔 개발 환경을 최신화하기로 했다.</p> <p>예전부터 사용해 보고 싶었던 번들러는 Vite다. Vite의 가장 큰 특징은 devServer에서 소스코드와 디펜던시를 두 가지 카테고리로 나누어 빌드하고, ESM 환경인, 브라우저에 빠르게 제공한다는 점이다. devServer가 cold-start 될 때 현재 페이지에서 필요한 정보만 아주 빠르게 실행시킬 수 있다. 이 말은, 코드 베이스 또는 라이브러리(사용하고 있는 node_modules 디펜던시)의 모든 파일을 번들링 하여 제공하는 것이 아니라, 현재 필요한 모듈만 골라내어 빠르게 제공한다는 뜻이다. Vite 가이드에서 가장 먼저 이야기하고 있는 것이 ESM을 통한 devServer start 속도이다.</p> <p>사전 번들링은, esBuild를 통해 디펜던시를 빌드하고, 변경이 잦은 소스코드는 ESM으로 제공한다. 기존에 Webpack과 같은 번들러는 모든 파일을 빌드 및 번들링 해야만 브라우저에서 구동이 가능했다. Vite는 소스코드를 ESM으로 제공하기 때문에 브라우저에서 동적 import를 통해 원하는 JavaScript 파일만 실행시킬 수 있다. 이 매커니즘에 따라 Webpack의 Node.js에서만 가능했던 기능이 브라우저에서 동작하기 위해 어떻게 Vite가 해결했는지를 알아볼 것이다.</p> <br/> diff --git a/tags/bundler/index.html b/tags/bundler/index.html index 5fdab6526..5bac8988d 100644 --- a/tags/bundler/index.html +++ b/tags/bundler/index.html @@ -109,7 +109,7 @@ 'M17.5306 13.5882C16.6384 13.8558 15.689 14 14.7044 14C9.5004 14 5.28174 9.97061 5.28174 5.00005C5.28174 3.32422 5.76127 1.75538 6.59643 0.411865C2.77326 1.55853 0 4.96994 0 9.00001C0 13.9706 4.21866 18 9.42265 18C12.8721 18 15.8887 16.2296 17.5306 13.5882Z' );clip-path:path( 'M17.5306 13.5882C16.6384 13.8558 15.689 14 14.7044 14C9.5004 14 5.28174 9.97061 5.28174 5.00005C5.28174 3.32422 5.76127 1.75538 6.59643 0.411865C2.77326 1.55853 0 4.96994 0 9.00001C0 13.9706 4.21866 18 9.42265 18C12.8721 18 15.8887 16.2296 17.5306 13.5882Z' - );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Bundler

A collection of 2 posts

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

+ );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Bundler

A collection of 2 posts

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.

ESLint로 import 구문에 규칙 넣기 cover image
Environment,  ESLint

ESLint로 import 구문에 규칙 넣기

규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.

TypeScript의 기본개념과 환경설정 cover image
TypeScript,  Environment

TypeScript의 기본개념과 환경설정

TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

+ );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Environment

A collection of 4 posts

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기

ESLint로 import 구문에 규칙 넣기 cover image
Environment,  ESLint

ESLint로 import 구문에 규칙 넣기

규칙을 가지고 import 구문이 정리된다면, 해당 파일에서는 어떤 종속성을 가지고 있고 어떤 기능을 사용하는지 한 눈에 파악하기 쉬울 것이다.

TypeScript의 기본개념과 환경설정 cover image
TypeScript,  Environment

TypeScript의 기본개념과 환경설정

TypeScript 환경설정을 통해 웹 환경 추세를 알아보자. (feat. allowImportingTsExtensions)

Webpack5 JavaScript 보일러플레이트 만들기 cover image
Bundler,  Webpack,  Environment

Webpack5 JavaScript 보일러플레이트 만들기

모던 프론트엔드 웹 개발에 필요한 세팅을 직접 해보면서 어떤 옵션과 기능이 있는지 알아보자.

Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite는 브라우저 환경에서 환경 변수 값을 다루고 HMR을 위해 import.meta를 활용한다.

+ );border-radius:50%;-webkit-transition:all 0.45s ease;transition:all 0.45s ease;}body .theme-toggler .mode:before{content:'';position:absolute;z-index:-1;top:50%;left:50%;-webkit-transform:translateX(-50%) translateY(-50%);-moz-transform:translateX(-50%) translateY(-50%);-ms-transform:translateX(-50%) translateY(-50%);transform:translateX(-50%) translateY(-50%);width:5px;height:5px;opacity:0;background:inherit;border-radius:50%;-webkit-transition:box-shadow 0.4s 0s ease;transition:box-shadow 0.4s 0s ease;}body .theme-toggler .mode:after{content:'';position:absolute;top:-20%;left:30%;width:90%;height:90%;background:rgb(255 255 255 / 1);border-radius:50%;-webkit-transition:all 0.3s ease;transition:all 0.3s ease;}body .theme-toggler .mode:hover{opacity:1;}body .theme-toggler:hover{background:rgb(215 215 215 / 0.9);}body .theme-toggler.is-white .mode{background:#fff;}body .theme-toggler.is-white:hover{background:rgb(215 215 215 / 0.2);}body.dark .theme-toggler{background:transparent;}body.dark .theme-toggler:hover{background:rgb(255 255 255 / 0.1);}body.dark .theme-toggler .mode{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);transform:scale(0.5);overflow:initial;opacity:0.8;background:white;-webkit-clip-path:none;clip-path:none;}body.dark .theme-toggler .mode:before{opacity:1;box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}body.dark .theme-toggler .mode:after{-webkit-transform:translateX(50%) translateY(-50%);-moz-transform:translateX(50%) translateY(-50%);-ms-transform:translateX(50%) translateY(-50%);transform:translateX(50%) translateY(-50%);opacity:0;-webkit-transition:background 0.45s ease;transition:background 0.45s ease;}body.dark .theme-toggler.is-white .mode:before{box-shadow:0 -16px 0 0 white,0 16px 0 0 white,-16px 0 0 0 white,16px 0 0 0 white,12px 12px 0 0 white,12px -12px 0 0 white,-12px 12px 0 0 white,-12px -12px 0 0 white;}

Vite

A collection of 1 post

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR) cover image
Bundler,  Vite,  Environment

Vite에서 import.meta는 왜 사용하는 걸까? (feat. HMR)

Vite의 철학에 기반한 방식 import.meta에 대한 이야기