[ 살펴보기 ] Vite - Basics
![[ 살펴보기 ] Vite - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1736059663341/67953923-9838-4a4a-845d-42ac5f0fb768.jpeg)
과거에는 React 초기 세팅을 위해 Create-React-App을 많이 사용했지만 이제는 Vite라는 좋은 tool이 존재하기에 NextJS와 같은 framework를 사용하는 것이 아니라면 React project를 위해 Vite가 많이 사용된다.
현재 Vite ( v6 )는 development 환경에서 dependencies를 prebuild하기 위해서 esbuild를 사용하고 production code를 위한 bundling 작업은 rollup을 사용하고 있지만 Rolldown이라는 rust 기반 bundler가 개발 진행중에 있으며 Rolldown bundler가 stable 단계에 이르면 esbuild와 rollup 모두 대체하여 사용될 것이라고 한다.
Vite는 Single Site Application 제작을 위한 build tool로 사용할 수도 있고 javascript library 제작을 위한 build tool로도 사용할 수 있다. Vite는 특정 framework에만 한정된 build tool이 아니며 React, vue, angular등 원하는 framework를 선택해서 개발할 수 있다.
Create project
Vite를 통해 project를 생성하기 위해서 다음 command를 실행한다.
npm create vite@latest
위의 command를 실행하면 다음과 같이 proejct name과 사용할 framework를 선택하고 기타 설정 값 선택하는 prompt가 나온다.

위의 command를 통해 project를 생성하면 project에 필요한 package는 install되지 않은 상태이므로 project 경로로 이동하여 package는 따로 install 해주어야 한다.
package가 모두 설치되었다면 npm run dev command를 통해 dev server를 실행할 수 있고 npm run build를 통해 project를 build할 수 있다. build된 project를 local에서 확인 하기 위해선 npm run preview command를 사용한다.
Typescript
npm create vite@latest command를 통해 project 생성 시 typescript를 포함하여 생성 했다면 별다른 추가 설정 없이 바로 proejct에 typescript를 사용할 수 있다. 또한 type만 export하는 file에서 type만 import하는 경우라면 불필요한 파일이 bundle에 포함되는 사항이 생기지 않도록 type-only import syntax를 사용한다.
import type { User } from 'types/user'
그리고 Vite는 typescript를 transpile할 때 type check 과정을 거치지 않고 type check는 IDE와 build process에서 처리된다고 가정한다. Transpile 과정이 각 파일마다 개별적으로 수행될 수 있는 반면 type checking을 위해선 연관된 전체 module graph가 필요하기에 성능을 위해 transpile 과정에 type check를 수행하지 않는다고 Vite team은 말한다. ( Reference - Transpile Only )
Vite 기반 project에서도 typescript configuration은 tsconfig.json를 통해 이루어 지며 Vite 기반 project에서 typescript 관련 설정 시 몇 가지 주의 사항이 있다.
isolatedModules : tsconfig.json 설정 파일에서 isolatedModules option이 true로 설정되어 있어야 한다. 위에서 언급 되었듯이 Vite는 typescirpt를 esbuild로 transpile하며 transpile시 type check를 함께 수행하지 않는다. 하지만
const enum을 reference하는 code와 같은 경우는 transpile시 올바른 output 생성을 위해 type check이 포함되어야 하기에 Vite로 transpile된 output code는 runtime에서 문제가 발생할 수도 있다.declare const enum Numbers { Zero = 0, One = 1, } console.log(Numbers.Zero + Numbers.One);그리고 isolatedModules option을 true로 설정하면 위의 코드와 같이 tsc가 아닌 다른 transpiler를 사용하여 transpile 했을 때 문제가 될 수 있는 code를 사용할 때 관련 type errror를 발생시켜 준다. ( Reference - isolatedModules )
useDefinForclassFields : typescript class field가 javascript로 transpile되는 형식에 영향을 주는 option이다. Vite 2.5.0부터 compilerOptions target이
ES2022이상일 때 default로 true가 된다. ( Reference - useDefineForClassFields )target : Vite는 transpile을 esbuild를 통해 수행하기에 tsconfig.json의 target은 transpile output target 설정에 사용되지 않는다 ( 그럼에도 useDefinForclassFields option을 사용되기에 target을
ES2022이상 값으로 설정해두는 것이 좋다 )Vite의 build target 설정은 tsconfig.json가 아닌
vite.config.ts파일을 통해 할 수 있다.vite.config.ts
import { defineConfig } from "vite"; export default defineConfig({ build: { target: "es2020", }, });
위의 compiler option 이외에 build 결과에 영향을 미치는 option은 documentation을 통해 확인할 수 있다. ( Reference - Other Compiler Options Affecting the Build Result )
JSX, TSX
.jsx, .tsx 파일 역시 별 다른 추가 설정 없이 바로 사용할 수 있다. JSX transpilation 역시 esbuild를 통해 이루어진다.
Client types
typescript는 default로 css, svg, jpg등과 같은 static asset을 valid module로 인식하지 않는다. 이를 해결하기 위해 declaration 파일을 하나 생성 하고 다음 코드를 추가 해준다.
vite-env.d.ts
/// <reference types="vite/client" />
또는 tsconfig.json 파일에 다음과 같이 types property를 추가해도 된다.
tsconfig.json
{
"compilerOptions": {
...
"types": ["vite/client"]
}
}
위의 설정을 추가하면 svg, jpg와 같은 assets import에 대한 type 에러가 발생하지 않고 import.meta.env, import.meta.hot에 대한 type도 정상적으로 처리된다.
Static Assets
static assets을 import할 시 해당 asset의 public URL이 return된다. 예를 들어 project 구조가 다음과 같다고 가정해보자.
/public
/images
- test1.jpg
/src
/assets
- react.svg
App.tsx
App.tsx
import reactLogo from "./assets/react.svg";
import testImage from "/images/test1.jpg";
function App() {
console.log({ testImage, reactLogo });
return (
...
);
}
export default App;
위의 예제에서 import한 testImage와 reactLogo asset은 다음 uri로 return된다.
{
"testImage": "/images/test1.jpg",
"reactLogo": "/src/assets/react.svg"
}
위의 예제와 같이 assets 파일을 src folder 안에서 관리할 수도 있지만 project root 경로에 있는 public folder에서 관리할 수도 있다. 차이점은 src folder안에서 관리하는 assets file은 build시 file 이름에 react-CHdo91hT.svg와 같이 hash 정보가 추가되는 반면 public folder에서 관리하는 asset은 build 후에도 asset 파일 이름이 변경되지 않는다.
public folder에서 관리하는 asset을 조회할 때는 다음과 같이 root path ( / )를 통해 조회한다.
import testImage from "/images/test1.jpg";
...
만약 public folder를 다른 folder로 변경하고 싶다면 vite configuration file의 publicDir option을 통해 변경할 수 있다. ( Reference - publicDir )
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
publicDir:"public"
});
Command Line Interface
Vite를 통해 실행할 수 있는 대표적인 CLI는 다음과 같다.
vite : vite를 통해 dev server를 실행한다.
vite dev또는vite servecommand를 대신 사용해도 된다.--portoption을 통해 dev server의 port를 설정할 수도 있고--openoption을 통해 dev server를 실행시키며 browser를 자동으로 open할 수도 있다. vite command와 함께 사용할 수 있는 모든 option list는 documentation을 통해 확인할 수 있다. ( Reference - Options )npx vite --port 4000vite build : vite를 통해 project를 build한다.
--outDiroption을 통해 build output path를 지정할 수 있고 ( default : dist )--configoption을 통해 build시 사용하는 configuration file을 별도로 설정할 수도 있다. build와 함께 사용할 수 있는 option list는 documentation을 통해 확인할 수 있다. ( Reference - Options )npx vite buildvite preview : build를 통해 생성한 production code를 local에서 미리 확인할 때 사용할 수 있다. Local에서 production code를 preview하기 위한 command이므로 production server에서 사용은 권장하지 않는다. 마찬가지로 함께 사용할 수 있는 option은 documentation을 통해 확인할 수 있다. ( Refernce - Options )
npx vite preview
Plugins
Vite가 기본적으로 제공하는 기능 외에 다른 기능이 필요하다면 plugin을 적용할 수 있다. 예를 들어 다음은 react project에 필요한 react plugin을 적용한 예제다.
vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
export default defineConfig({
plugins: [react()],
});
Vite plugin은 default로 dev server를 통해 실행할 때도 적용되고 build를 수행할 때도 적용이 된다. 만약 특정 plugin을 build 또는 dev시에만 적용하고 싶다면 apply property를 통해 plugin이 언제 적용 되어야 하는지 설정할 수 있다. 설정할 수 있는 option은 build 또는 serve로 설정할 수 있다.
import typescript2 from 'rollup-plugin-typescript2'
import { defineConfig } from 'vite'
export default defineConfig({
plugins: [
{
...typescript2(),
apply: 'build',
},
],
})
Vite가 지원하는 official plugin은 documentation plugins section에서 확인할 수 있고 community plugins은 awesome-vite를 통해 확인할 수 있다.
Env variables
Vite는 dotenv를 통해 project root에 선언된 .env, .env.local 등의 file에서 environment variables을 load한다. create vite를 통해 project를 생성했다면 .env.local은 gitignore에 포함되어 있지만 .env는 gitignore에 포함되어 있지 않으므로 필요시 별도로 추가해주자.
또한 다음과 같이 applicaton이 실행되는 mode에 따라 적용할 env 파일을 따로 구성할 수도 있다.
.env.production.local
VITE_MY_NAME=Karl
.env.development.local
VITE_MY_NAME=Paul
App.tsx
import "./App.css";
function App() {
return (
<>
<div>{import.meta.env.VITE_MY_NAME}</div>
</>
);
}
export default App;
위의 예제에서 application을 dev mode로 실행하면 environment variable VITE_MY_NAME은 Paul이 되고 build를 실행할 땐 Karl이 된다.
만약 .env 또는 .env.local에도 VITE_MY_NAME라는 environment variable이 있다면 .env.production.local 또는 .env.development.local과 같이 특정 mode 정보를 포함한 env 파일에 설정한 값이 적용된다.
위의 예제에서 볼 수 있듯이 vite에선 import.meta.env object를 통해 environment variable에 접근할 수 있다. 다만 VITE_로 시작하는 이름을 가진 environment variable만 import.meta.env를 통해 접근 가능하며 VITE_로 시작하는 environment variable의 value는 client code에 포함되므로 노출되면 안되는 value는 VITE_로 시작하는 environment variable에 설정하지 않도록 주의한다.
추가로 기본적으로 사용할 수 있는 built-in env variables은 다음과 같다.
import.meta.env.MODE : 현재 application이 실행되고 있는 mode.
import.meta.env.BASE_URL : application이 serve 되고 있는 base url.
import.meta.env.PROD : applicaton이 production mode로 실행되고 있다면 true를 반환한다.
import.meta.env.DEV : application이 dev mode로 실행되고 있다면 true를 반환한다.
import.meta.env.SSR : application이 server 환경에서 실행되고 있는지 여부를 반환한다.
만약 typesciprt를 사용한다면 vite는 위에서 소개한 built-in env vairables에 대한 type definition을 default로 제공한다. 만약 default로 제공되는 env variables type외에 project .env 파일에 추가한 environment variable에 대한 type definition을 추가하고 싶다면 src/vite-env.d.ts 파일에 다음과 같이 추가해준다.
src/vite-env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_MY_NAME: string;
readonly VITE_MY_ADDRESS: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
.env.local
VITE_MY_NAME=Paul
VITE_MY_ADDRESS=seoul
Vite에서는 다음과 같이 %ENV_NAME% 형태로 html 파일에서도 import.meta.env를 통해 접근할 수 있는 environment variable을 사용할 수 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div>Env name : %VITE_MY_NAME%</div>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Vite는 default로 dev command ( vite dev, vite serve )를 통해 실행할 때 development mode로 실행되고 build를 수행할 땐 production mode로 실행된다. 그리고 위에서 살펴봤듯이 vite가 실행되는 mode에 따라서 사용되는 env 파일 역시 달라진다. 만약 dev나 build시 실행되는 mode를 변경하고 싶다면 다음과 같이 --mode option을 사용할 수 있다.
npx vite build --mode test
위의 command를 실행했을 때 .env.test.local과 같이 test mode에 대한 env 파일이 존재한다면 해당 env 파일이 사용된다. 여기서 주의할 점은 --mode option을 통해 설정하는 mode가 process.env.NODE_ENV를 자동으로 변경해주진 않는다는 점이다. --mode를 통해 설정하는 mode와 process.env.NODE_ENV는 별개로 취급된다. 아래는 둘 사이의 command별 동작 테스트를 Official documentation에서 발췌한 내용이다.



![[ 살펴보기 ] RDB - Relationships](https://cdn.hashnode.com/res/hashnode/image/upload/v1739711556668/48dc9e84-a621-42aa-9c9f-5fc5c436f0ec.jpeg)
![[ 살펴보기 ] MySQL - Data types](https://cdn.hashnode.com/res/hashnode/image/upload/v1739593589113/530f8704-4d27-42c9-a451-bb5c63150b99.jpeg)
![[ 살펴보기 ] TypeORM - Transactions, Migration](https://cdn.hashnode.com/res/hashnode/image/upload/v1739106042581/980b8133-61d4-406a-a026-65be9c28eace.jpeg)
![[ 살펴보기 ] TypeORM - Relations](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666874402/b688bd0b-b6bb-4f43-87d8-c1b46b59f1b7.jpeg)
![[ 살펴보기 ] TypeORM - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666803591/bef5df17-7dc7-4123-ae55-004d5042df39.jpeg)