Vite 씨, 왜 그렇게 빌드하세요?

윤뿔소·2024년 10월 9일
1

CS 지식 / 다양한 팁

목록 보기
19/20
post-thumbnail

Vite + TS + React로 새 프로젝트를 설정하면, Vite는 특정한 구조와 설정 파일들을 생성합니다. 이는 빌드 및 배포 시 Vite만의 최적화를 담기 위해 생성됩니다.

근데 여기서 ts.config.jsontsconfig.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과 같은 기존의 번들러들은 이러한 복잡성을 다루기 위해 노력했지만, 동시에 새로운 문제점들을 야기했습니다.

  1. 느린 개발 서버 시작 : 대규모 프로젝트에서 Webpack의 개발 서버 시작 시간이 지나치게 길어지는 문제 발생. => 개발자의 생산성 저하.
  2. 복잡한 설정 : Webpack의 설정은 매우 많아 복잡하거나 어려울 수 있음. 러닝 커브가 상승했음.
  3. 무거운 번들 크기 : 설정을 해주지 않아 최적화되지 않은 번들은 앱의 성능을 저하시키는 주요 원인이 됨.
  4. 비효율적인 HMR : 기존의 HMR은 전체 번들을 다시 빌드하는 경우가 많아 비효율 초래.

새 술은 새 부대에 담아야한다고 하죠? 이러한 배경에서 Vite는 완전히 새로운 접근 방식을 제시했습니다. 그 중 하나의 전략인 빌드 환경의 Node.JS와 배포 환경의 App - Browser 관련 구조를 분리해 생각했죠.

주요 특징

그래서 아래와 같은 특징을 가지게 됐습니다.

  1. 환경 분리: tsconfig.app.jsontsconfig.node.json으로 Node.js 환경과 브라우저 환경 분리.
{
  "files": [],
  // Vite는 node 환경과 브라우저 환경을 분리해 빌드, tsconfig.json 파일을 분리해 관리.
  "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
}
  1. 보안 강화 : 환경 분리를 통해 Node.js 관련 코드가 클라이언트로의 노출 방지.

  2. 성능 최적화

    • Node.js 환경 : 빌드 시 성능 최적화.
    • 브라우저 환경 : 런타임 성능 및 번들 크기 최적화.
  3. API 사용 최적화

    • Node.js 환경 : fs, path 등 Node.js 특화 API 사용.
    • 브라우저 환경 : DOM, Web API 등 브라우저 특화 기능 사용.
  4. 모듈 시스템 차이 고려

    • Node.js 환경 : CommonJS 모듈 시스템 지원.
    • 브라우저 환경 : ES 모듈 시스템 사용.
  5. 타입 정의 최적화

    • Node.js 환경 : Node.js 관련 타입 정의.
    • 브라우저 환경 : DOM, Web 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"]
}

차이점 및 의도

1. 용도 및 적용 범위

  • tsconfig.app.json : 주로 브라우저에서 실행될 애플리케이션 코드에 적용
  • tsconfig.node.json : Vite의 설정 파일 및 빌드 스크립트 등 Node.js 환경에서 실행되는 코드에 적용

Vite는 개발 서버 실행 시 두 설정을 모두 사용하지만, 프로덕션 빌드 시에는 주로 tsconfig.app.json을 사용해 최종 번들을 생성합니다. 이때는 tsconfig.node.json는 빌드 스크립트만 적용하거든요!

2. targetlib 설정

  • 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 기능을 활용해 빌드 프로세스를 최적화하고, 브라우저 환경에서는 더 넓은 호환성을 위해 약간 낮은 버전을 타겟으로 합니다.

3. JSX 지원

  • tsconfig.app.json : "jsx": "react-jsx"
  • tsconfig.node.json : JSX 관련 설정 없음

tsconfig.app.json만 React JSX를 지원합니다.

Vite는 브라우저에서 실행될 React 컴포넌트를 올바르게 컴파일하고, Node.js 환경에서는 불필요한 JSX 처리를 피해 빌드 성능을 향상시킵니다.

4. 포함 파일

  • tsconfig.app.json : "include": ["src"]
  • tsconfig.node.json : "include": ["vite.config.ts"]

각 설정 파일이 다른 소스 파일을 대상으로 합니다.

Vite는 애플리케이션 코드와 설정 코드를 명확히 구분해 처리합니다. 이를 통해 빌드 프로세스의 효율성을 높이고, 각 환경에 맞는 최적화를 적용할 수 있습니다. 보안도 덤이구요!

5. 모듈 해석

  • 두 파일 모두 : "moduleResolution": "bundler", "module": "ESNext"

둘 다 최신 모듈 시스템을 사용합니다.

Vite는 ESM을 기본으로 사용해 빠른 개발 서버 시작과 효율적인 코드 분할을 가능하게 합니다.

6. 컴파일 출력

  • 두 파일 모두 : "noEmit": true

TS 컴파일러가 직접 출력 파일을 생성하지 않습니다.

Vite가 TS 컴파일과 번들링을 직접 제어해 최적화된 빌드 프로세스를 구현합니다.

Vite의 특징을 담은 빌드 과정

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가 이 과정을 최적화해 처리합니다. 이를 통해 개발자들은 타입 체크의 이점을 누리면서도 효율적인 빌드 결과물을 얻을 수 있습니다.

나열된 특징을 축약하자면,

  1. 개발 서버를 위해 Node.js 환경에서 최신 JS 기능과 HMR을 활용한 빠른 개발 환경 제공을 위해 tsconfig.node.json 사용
  2. 배포 환경을 위해 tsconfig.app.json을 통한 브라우저 호환성과 React JSX 지원
  3. ESM 기반의 효율적인 모듈 로딩과 코드 분할
  4. Vite의 직접적인 TS 컴파일 및 번들링 제어를 통한 최적화

즉, 환경별 최적화를 위해 이런 구조를 채택한 것입니다! 이렇게 분리함으로써 개발자들에게 알맞는 개발 환경과 최적화된 프로덕션 빌드를 동시에 제공합니다. 또, 각 환경에 맞는 최적의 도구와 설정을 자동으로 적용해줍니다.

결론

Vite의 TS 설정 방식은 현대 웹 개발의 복잡한 요소들을 체계적으로 구조화해 웹 개발 방식을 재정립했습니다. 이 접근 방식은 '무릇 통찰은 관점의 변화에서 시작된다'는 진리를 번들러 - 빌드 도구에 적용한 것이라 볼 수 있습니다.

Node.js 환경과 브라우저 환경의 명확한 분리는 단순한 코드 구분이 아닌, '시야를 넓히는 관심사의 분리'입니다. 이렇게 분리를 하니 아래와 같은 효과가 나타났습니다.

  1. 환경별 최적화 : Node.js 환경과 브라우저 환경을 명확히 구분해 각 환경에 최적화된 설정 제공.
    • 각 환경에 맞는 ECMAScript 버전과 라이브러리를 사용해 성능 최적화.
  2. 빠른 개발 서버 : ESM을 기본으로 사용해 빠른 개발 서버 시작과 즉각적인 HMR을 지원하기 위해 최적화된 구조 사용.
  3. 효율적인 빌드 : 프로덕션 빌드 시 최적화된 번들을 생성하기 위해 환경별로 다른 설정 적용 필요.
  4. 타입 안정성 : TS를 사용해 개발 시 타입 안정성을 제공하고, 각 환경에 맞는 타입 정의 사용.
  5. 유연한 빌드 프로세스 : Vite가 TS 컴파일과 번들링을 직접 제어해 최적화된 빌드 결과물 생성.
  6. 모듈 시스템 최적화 : ES 모듈을 기본으로 사용하면서도, 필요한 경우 CommonJS 모듈 지원.

결국, Vite의 이러한 접근으로 HMR, 최신 JS 등 지원과 Code Splitting, Tree Shaking 등 번들 파일에 대해 최적화를 각각 구분하며 제공했습니다. 이는 결국 개발자와 사용자에게 이점을 제공함으로써, 일석이조의 효과를 거둬 번들러 + 빌드 도구로서 매력이 계속 상승했던 것입니다. Vite 최고!

참고

profile
코뿔소처럼 저돌적으로

0개의 댓글