Vite + TS + React로 새 프로젝트를 설정하면, Vite는 특정한 구조와 설정 파일들을 생성합니다. 이는 빌드 및 배포 시 Vite만의 최적화를 담기 위해 생성됩니다.
근데 여기서 ts.config.json
과 tsconfig.app.json
, tsconfig.node.json
3개가 생성되더라구요? 그래서 궁금해서 찾아봤습니다.
그랬더니 Vite 빌드 전략이 나오더라구요! 이 학습을 적어보겠습니다.
Vite 프로젝트를 실행시키면 아래와 같은 파일들이 생성됩니다.
vite.config.ts
: Vite 설정 파일.tsconfig.json
: TS 설정의 루트 파일.tsconfig.node.json
: Node.js 환경을 위한 TS 설정.tsconfig.app.json
: 브라우저 환경(React 앱)을 위한 TS 설정.src/
: 소스 코드 디렉토리.public/
: 정적 자산 디렉토리.index.html
: 진입점 HTML 파일.어어 그런데 tsconpig
를 분리시켰네요? 왜 그런 걸까요?
Vite는 빌드와 배포 환경을 분리해 유연함을 가지면서도, 빠른 환경을 만들기 위해 이런 구조를 채택했습니다. 아래와 같은 현대 빌드 도구 및 번들러를 지원하기 위해 분리했습니다.
현대 웹 개발은 복잡성과 규모가 급격히 증가하면서 다양한 도전에 직면하게 되었습니다. Webpack과 같은 기존의 번들러들은 이러한 복잡성을 다루기 위해 노력했지만, 동시에 새로운 문제점들을 야기했습니다.
새 술은 새 부대에 담아야한다고 하죠? 이러한 배경에서 Vite는 완전히 새로운 접근 방식을 제시했습니다. 그 중 하나의 전략인 빌드 환경의 Node.JS와 배포 환경의 App - Browser 관련 구조를 분리해 생각했죠.
그래서 아래와 같은 특징을 가지게 됐습니다.
tsconfig.app.json
과 tsconfig.node.json
으로 Node.js 환경과 브라우저 환경 분리.{
"files": [],
// Vite는 node 환경과 브라우저 환경을 분리해 빌드, tsconfig.json 파일을 분리해 관리.
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
}
보안 강화 : 환경 분리를 통해 Node.js 관련 코드가 클라이언트로의 노출 방지.
성능 최적화
API 사용 최적화
모듈 시스템 차이 고려
타입 정의 최적화
실제 코드를 관찰해보겠습니다. 차이점을 숙지하고 난 뒤 비교해보겠습니다.
tsconfig.app.json
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}
tsconfig.node.json
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}
tsconfig.app.json
: 주로 브라우저에서 실행될 애플리케이션 코드에 적용tsconfig.node.json
: Vite의 설정 파일 및 빌드 스크립트 등 Node.js 환경에서 실행되는 코드에 적용Vite는 개발 서버 실행 시 두 설정을 모두 사용하지만, 프로덕션 빌드 시에는 주로 tsconfig.app.json
을 사용해 최종 번들을 생성합니다. 이때는 tsconfig.node.json
는 빌드 스크립트만 적용하거든요!
target
및 lib
설정tsconfig.app.json
: "target": "ES2020"
, "lib": ["ES2020", "DOM", "DOM.Iterable"]
tsconfig.node.json
: "target": "ES2022"
, "lib": ["ES2023"]
tsconfig.node.json
은 더 최신 버전의 ECMAScript를 타겟으로 합니다.
Vite는 Node.js 환경에서 최신 JS 기능을 활용해 빌드 프로세스를 최적화하고, 브라우저 환경에서는 더 넓은 호환성을 위해 약간 낮은 버전을 타겟으로 합니다.
tsconfig.app.json
: "jsx": "react-jsx"
tsconfig.node.json
: JSX 관련 설정 없음tsconfig.app.json
만 React JSX를 지원합니다.
Vite는 브라우저에서 실행될 React 컴포넌트를 올바르게 컴파일하고, Node.js 환경에서는 불필요한 JSX 처리를 피해 빌드 성능을 향상시킵니다.
tsconfig.app.json
: "include": ["src"]
tsconfig.node.json
: "include": ["vite.config.ts"]
각 설정 파일이 다른 소스 파일을 대상으로 합니다.
Vite는 애플리케이션 코드와 설정 코드를 명확히 구분해 처리합니다. 이를 통해 빌드 프로세스의 효율성을 높이고, 각 환경에 맞는 최적화를 적용할 수 있습니다. 보안도 덤이구요!
"moduleResolution": "bundler"
, "module": "ESNext"
둘 다 최신 모듈 시스템을 사용합니다.
Vite는 ESM을 기본으로 사용해 빠른 개발 서버 시작과 효율적인 코드 분할을 가능하게 합니다.
"noEmit": true
TS 컴파일러가 직접 출력 파일을 생성하지 않습니다.
Vite가 TS 컴파일과 번들링을 직접 제어해 최적화된 빌드 프로세스를 구현합니다.
Vite의 빌드 프로세스는 개발 환경과 프로덕션 환경을 세심하게 구분해 각각의 장점을 최대한 활용합니다. 다시 한 번, 이 과정을 단계별로 살펴보겠습니다.
먼저, 개발 서버가 시작되면 Vite는 Node.js 환경에서 최신 JS 기능들을 활용합니다. 이때 tsconfig.node.json
설정을 기반으로 vite.config.ts
파일을 해석해 핫 리로딩(HMR)과 같은 개발 도구들을 설정합니다. 이러한 접근은 개발자들에게 즉각적인 피드백과 빠른 개발 경험을 제공해 DX를 올려줍니다.
브라우저에서 실행될 코드는 tsconfig.app.json
설정을 따르며, 이는 더 넓은 브라우저 호환성을 고려합니다. /src
디렉토리의 코드들은 ES2020을 타겟으로 하며, DOM API와 React JSX를 지원하도록 컴파일됩니다. 이를 통해 개발자들은 최신 문법을 사용하면서도 안정적인 브라우저 지원을 보장받을 수 있습니다.
Vite는 ESModule을 기본으로 채택해 필요한 모듈만 즉시 불러오는 방식을 사용합니다. 이는 개발 서버의 시작 시간을 획기적으로 단축시키며, 프로덕션 환경에서는 효율적인 코드 분할을 가능하게 합니다.
마지막으로, TS 컴파일과 번들링 과정을 Vite가 직접 제어합니다. 두 설정 파일 모두 noEmit: true
로 설정되어 있어 TS 컴파일러는 파일을 직접 생성하지 않고, 대신 Vite가 이 과정을 최적화해 처리합니다. 이를 통해 개발자들은 타입 체크의 이점을 누리면서도 효율적인 빌드 결과물을 얻을 수 있습니다.
나열된 특징을 축약하자면,
tsconfig.node.json
사용tsconfig.app.json
을 통한 브라우저 호환성과 React JSX 지원즉, 환경별 최적화를 위해 이런 구조를 채택한 것입니다! 이렇게 분리함으로써 개발자들에게 알맞는 개발 환경과 최적화된 프로덕션 빌드를 동시에 제공합니다. 또, 각 환경에 맞는 최적의 도구와 설정을 자동으로 적용해줍니다.
Vite의 TS 설정 방식은 현대 웹 개발의 복잡한 요소들을 체계적으로 구조화해 웹 개발 방식을 재정립했습니다. 이 접근 방식은 '무릇 통찰은 관점의 변화에서 시작된다'는 진리를 번들러 - 빌드 도구에 적용한 것이라 볼 수 있습니다.
Node.js 환경과 브라우저 환경의 명확한 분리는 단순한 코드 구분이 아닌, '시야를 넓히는 관심사의 분리'입니다. 이렇게 분리를 하니 아래와 같은 효과가 나타났습니다.
결국, Vite의 이러한 접근으로 HMR, 최신 JS 등 지원과 Code Splitting, Tree Shaking 등 번들 파일에 대해 최적화를 각각 구분하며 제공했습니다. 이는 결국 개발자와 사용자에게 이점을 제공함으로써, 일석이조의 효과를 거둬 번들러 + 빌드 도구로서 매력이 계속 상승했던 것입니다. Vite 최고!