๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
FE/vite

[vite] ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ Vite 101

by livemehere 2023. 10. 10.

๐Ÿง‘‍๐Ÿญ๏ธ Vite ๋Š” Esbuild + Rollup ์œผ๋กœ ๋งŒ๋“ค์–ด์ง„ ์ฐจ์„ธ๋Œ€ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

vite ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ™˜๊ฒฝ์— ํ•„์š”ํ•œ config ๋ฅผ ๋ชจ๋‘ ์ œ๊ณตํ•˜๊ณ ์žˆ๋Š” ๋น ๋ฅด๊ณ , ๊ฐ„๋‹จํ•œ no-configuration ํˆด์ž…๋‹ˆ๋‹ค. 

๊ธฐ์กด์˜ ๋ฒˆ๋“ค๋Ÿฌ ๊ธฐ๋ฐ˜์˜ ๋„๊ตฌ๋“ค์€, ๊ฐœ๋ฐœ์„œ๋ฒ„๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•  ๋•Œ ์ฝœ๋“œ ์Šคํƒ€ํŠธ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ๋˜๋ฉด ๋ชจ๋“  ์†Œ์Šค์ฝ”๋“œ์— ๋Œ€ํ•œ ํฌ๋กค๋ง๊ณผ ๋นŒ๋“œ์ž‘์—…์ด ํ•„์š”ํ•˜๋ฉฐ, ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์ง„๋‹ค๋ฉด ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ๊ฐ€๋™ํ•˜๋Š”๋ฐ ๋น„ํ•ฉ๋ฆฌ์ ์œผ๋กœ ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. vite ๋Š” ๋ชจ๋“ˆ์„ dependencies ์™€ source code ๋‘ ์นดํ…Œ๊ณ ๋ฆฌ๋กœ ๋‚˜๋ˆ„์–ด ์ด๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

(1) Dependencies ๋Š” ๋‹ค์šด๋ฐ›์€ ์™ธ๋ถ€ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. ์ฆ‰, node_modules ํŒจํ‚ค์ง€๋“ค์„ ๋งํ•˜๋Š”๋ฐ, ์ด๊ฒƒ๋“ค์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š” ์˜์—ญ์ž„์œผ๋กœ, ๋ฒˆ๋“ค๋ง ํ•  ๋•Œ ๋งˆ๋‹ค ๋งค๋ฒˆ ํ‰๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†๋Š” ์š”์†Œ๋“ค์ž…๋‹ˆ๋‹ค. vite ๋Š” ์ด ํŒจํ‚ค์ง€๋“ค์„ ๋ชจ๋‘ Esbuild ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์ „ ๋ฒˆ๋“ค๋งํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ‘ ์‚ฌ์ „ ๋ฒˆ๋“ค๋ง์„ ํ†ตํ•ด์„œ CommonJS, UMD ๋ชจ๋“ˆ์„ ๋ชจ๋‘ ESM ์œผ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Esbuild ๋Š” ๊ฐ„๋‹จํžˆ ์†Œ๊ฐœํ•˜์ž๋ฉด, Go ๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ฒˆ๋“ค๋ง ํˆด์ž…๋‹ˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์–ธ์–ด์  ํ•œ๊ณ„๋ฅผ ๋„˜์–ด ๋นŒ๋“œ ์†๋„๊ฐ€ 10~ 100๋ฐฐ ๋น ๋ฅธ ์žฅ์ ์ด์žˆ์ง€๋งŒ, code splitting, css ์ฒ˜๋ฆฌ, es5 ์ดํ•˜ ๋ฌธ๋ฒ• ์ฒ˜๋ฆฌ ๋“ฑ ์ด๊ฒƒ์ €๊ฒƒ ์•ˆ์ •์„ฑ ๋ฌธ์ œ๊ฐ€ ์ž”์žฌํ•ฉ๋‹ˆ๋‹ค. vite ๋Š” ๊ฐœ๋ฐœํ™˜๊ฒฝ์‹œ์—๋งŒ ๋น ๋ฅธ ๋นŒ๋“œ์šฉ๋„๋กœ ์ด๊ฒƒ์„ ์‚ฌ์šฉํ•˜๊ณ , ์ตœ์ข… ๋นŒ๋“œ์‹œ์—๋Š” ์•ˆ์ •์ ์ธ Rollup ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

(2) Source code ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค. ์ด๋ถ€๋ถ„์€ ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.

์•ž์„œ ์‚ฌ์ „์— ๋ฒˆ๋“ค๋งํ•œ ํŒจํ‚ค์ง€๋“ค๊ณผ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด์„œ vite ๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ Native ๋ชจ๋“ˆ์ธ ESM ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํŒจํ‚ค์ง€๋“ค๊ณผ ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ž์ฃผ ๋ณ€๊ฒฝ๋˜๋Š” Source code ์˜์—ญ์„ ํ•˜๋‚˜์˜ ESM ๋ชจ๋“ˆ๋กœ ์ œ๊ณตํ•จ์œผ๋กœ์จ ๋‹จ๋…์ ์œผ๋กœ ๋ธŒ๋ผ์šฐ์ €์—๊ฒŒ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๐Ÿญ ์ตœ์ข… ๋นŒ๋“œ์—๋Š” Rollup ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

Esbuild ๋Š” ํ˜„์žฌ ์–ด๋–ค ๋ฒˆ๋“ค๋ง ํˆด ๋ณด๋‹ค ๊ฐ€์žฅ๋น ๋ฅธ ์„ฑ๋Šฅ์„ ์ž๋ž‘ํ•˜์ง€๋งŒ ์•„์‰ฌ์šด ์ƒํƒœ๊ณ„์™€ ๋ธŒ๋ผ์šฐ์ €์šฉ ๋ฒˆ๋“ค๋ง์—์„œ ์•„์ง์€ ๋‹ค๋ฅธ ํˆด๋ณด๋‹ค ์•ˆ์ •์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๋Š” ํ‰๊ฐ€๊ฐ€ ์žˆ์–ด ์•ˆ์ •์„ฑ๊ณผ ์ƒํƒœ๊ณ„๊ฐ€ ๋น„๊ต์  ๋” ํฐ Rollup ์„ ์„ ํƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ์œ ์—ฐํ•˜๊ณ  ๋ฐฉ๋Œ€ํ•œ ์ƒํƒœ๊ณ„๋ฅผ ์ ๊ทน ์ฑ„์šฉํ•จ์œผ๋กœ์จ vite ๊ฐ€ ์„ฑ๊ณตํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค๊ณ  ๋งํ•˜๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ ‡์ง€๋งŒ esbuild ๋„ ํ•ด๋ฅผ ๊ฑฐ๋“ญํ•˜๋ฉฐ ๋ฐœ์ „ํ•˜๊ณ ์žˆ๊ณ , ๊ทธ ์žฅ์ ์ด ๋งŽ๊ธฐ ๋•Œ๋ฌธ์— ์ ์ฐจ ๋นŒ๋“œ์— ๋„์›€ํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

 

โœ๏ธ Vite ๊ฐ€ ์ง€์›ํ•˜๋Š” ๊ธฐ๋Šฅ

vite ๋Š” ๋‹จ์ˆœํžˆ ๋„ค์ดํ‹ฐ๋ธŒ ESM ์™ธ์—๋„ ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์ œ๊ณตํ•˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

node_modules ์ง€์›

์•„๋ž˜ ์ฝ”๋“œ๋Š” ESM ์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

import dayjs from 'dayjs';

dayjs ๋ชจ๋“ˆ์œ„์น˜๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์ธ๋ฐ์š”.

์ต์ˆ™ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋Š” npm ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” node ํ™˜๊ฒฝ์˜ commonjs ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ESM ์—์„œ ๊ทธ๋Œ€๋กœ ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” node_modules ์˜ ๋ชจ๋“  ํŒจํ‚ค์ง€๋ฅผ ๊ฐœ๋ฐœ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ๋กœ ์ œ๊ณตํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.

vite ๋Š” Esbuild ๋กœ node_modules ์˜ ๋ชจ๋“  ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์ „ ๋ฒˆ๋“ค๋งํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์ด serving ํ•˜๊ณ  ์บ์‹œํ•ฉ๋‹ˆ๋‹ค.

/node_modules/.vite/deps/dayjs.js?v=b09621d8

 

 

Hot Module Replacement

vite ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ  ESM ์„ ํ†ตํ•ด์„œ hmr ์„์ง€์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ฌด ์„ค์ •์—†์ด ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ด๋„, ์ƒˆ๋กœ๊ณ ์นจ ์—†์ด ๋ฐ˜์˜์ด๋ฉ๋‹ˆ๋‹ค.

react, vue ์™€ ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ์˜ ๊ฒฝ์šฐ ๋ณ„๋„์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ œ๊ณตํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋˜ํ•œ ๊ฐ ํ”„๋ ˆ์ž„์›Œํฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์— ๋‚ด์žฅ๋˜์–ด์žˆ์–ด, ๋ณ„๋„์˜ ์„ค์ •์ด ํ•„์š”์—†์Šต๋‹ˆ๋‹ค.

 

Typescript

vite ๋Š” .ts ํŒŒ์ผ ์ปดํŒŒ์ผ ๋ฐ import ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

html ํŒŒ์ผ์—์„œ๋„ ๊ฐ€๋Šฅํ•˜๋ฉฐ ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

<body>
    <h1>Hello Vite!</h1>
    <script src="src/index.ts" type="module"></script>
</body>

๋‹จ, ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง๋งŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” ๋‹ค๋ฅธ ๋ฒˆ๋“ค๋Ÿฌ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํŠธ๋žœ์ŠคํŒŒ์ผ๋ง๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ , ํƒ€์ž… ์ฒดํฌ๋Š” IDE ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ , build ํƒ€์ž„์—๋งŒ ์ฒดํฌํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค.

ํƒ€์ž… ์ฒดํฌ๋ฅผ ํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์ „์ฒด ๋ชจ๋“ˆ ๊ทธ๋ž˜ํ”„์— ๋Œ€ํ•œ ํƒ์ƒ‰์ด ํ•„์š”ํ•œ ์ž‘์—…์ด๊ธฐ ๋•Œ๋ฌธ์—, vite ์˜ ์†๋„ ์ด์ ๋„ ์‚ฌ๋ผ์ง€๊ฒŒ ๋  ๋ฟ ์•„๋‹ˆ๋ผ, ๋‹ค๋ฅธ ๋ฒŒ๋“ค๋Ÿฌ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ํƒ€์ž…์ฒดํ‚น์— ์†Œ๋น„๋˜๋Š” ์‹œ๊ฐ„์ด ์ปค์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ์ •์  ๊ฒ€์‚ฌ๋Š” ๋ฒˆ๋“ค๋ง ํŒŒ์ดํ”„๋ผ์ธ์—์„œ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

ํƒ€์ž… ์—๋Ÿฌ๋ฅผ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ™•์ธ ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ vite-plugin-checker ๊ถŒ์žฅํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

vite ์—์„œ typescript ๋Š” Esbuild ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ ์žˆ๊ณ , tsc ๋Œ€๋น„ 20~30๋ฐฐ ๋น ๋ฅธ ํฌํผ๋จผ์Šค๋ฅผ ๋ณด์ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํƒ€์ž…๋งŒ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ ์ž˜๋ชป ๋ฒˆ๋“ค๋ง ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ํƒ€์ž…์ „์šฉ imports, exports ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์šฐํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import type { T } from 'only/types'
export type { T }

 

โš ๏ธ typescript ์ปดํŒŒ์ผ ์˜ต์…˜ ์ฃผ์˜์‚ฌํ•ญ

 

isolatedModules : true

Esbuild ๋Š” ํƒ€์ž…์—๋Œ€ํ•œ ์ •๋ณด ์—†์ด ๋ณ€ํ™˜๋งŒ์„ ์ˆ˜ํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, enum ํ˜น์€ ์•”์‹œ์ ์ธ ํƒ€์ž… import ๊ฐ€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ˆ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๋ผ, ์ด์˜ต์…˜์„ true ๋กœ ์„ค์ •ํ•˜์—ฌ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

 

skipLibCheck : true

์œ„ ์„ค์ •์„ true ๋กœ ํ–ˆ์„ ์‹œ vue ๋Š” ํƒ€์ž…์ฒดํ‚น์ด ์ •์ƒ์ ์œผ๋กœ ๋˜์ง€ ์•Š๋Š” ๋ฒ„๊ทธ๊ฐ€์žˆ์Šต๋‹ˆ๋‹ค. vue ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด์˜ต์…˜์„ true ๋กœ ์ฒดํฌํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

 

useDefineForClassFields : true

vite ๋Š” typescript ๋ณ€ํ™˜ ๋Œ€์ƒ์ด ESNext or ES2022 ์ธ ๊ฒฝ์šฐ ๊ธฐ๋ณธ๊ฐ’์„ true ๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” tsc ๋ฐ ECMAScript ํ‘œ์ค€์„ ๋”ฐ๋ฅด๋„๋ก ํ•˜๊ธฐ ์œ„ํ•จ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ๋„ ์ง€์›ํ•˜๋Š ๊ฒƒ์— ๋งž์ถฐ์„œ ์•Œ์•„๋ด์•ผ ํ•˜๊ฒ ์ง€๋งŒ ์•Œ๋ ค์ง„ ๊ฒƒ์œผ๋กœ๋Š” lit-element ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” false ๋กœ ์„ค์ •ํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

 

 

โŒจ๏ธ Client Types

vite ๊ฐ€ client ์—๊ฒŒ ์ฃผ์ž…ํ•˜๋Š” type ์„ 2๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ์ถ”๊ฐ€ํ•ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

- .svg ๋“ฑ์„ ๋น„๋กฏํ•œ ์—์…‹ import ํƒ€์ž…

- import.meta.env ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํƒ€์ž…

- import.meta.hot ์˜ HMR API ํƒ€์ž…

 

(1) *.d.ts ์„ ์–ธ ์ถ”๊ฐ€

/// <reference types="vite/client" />

 

(2) tsconfig.json ์— ๋ช…์‹œ์ ์œผ๋กœ ์ถ”๊ฐ€

{
  "compilerOptions": {
    "types": ["vite/client"]
  }
}

 

๋‹ค๋ฅธ๊ฑด ๋ชฐ๋ผ๋„, .svg ์™€๊ฐ™์€ ์—์…‹ import ๋Š” ์ˆ˜์ •ํ•  ๊ฒฝ์šฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด์„œ React ์—์„œ .svg ํŒŒ์ผ์„ import ํ• ๋•Œ react component ๋กœ import ํ•œ๋‹ค๊ณ  ํ•˜๋ฉด, ๊ธฐ๋ณธ๋™์ž‘์„ ์ˆ˜์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

// vite-override.d.ts
declare module '*.svg' {
  const content: React.FC<React.SVGProps<SVGElement>>
  export default content
}


// d.ts ํŒŒ์ผ
/// <reference types="./vite-env-override.d.ts" /> // vite/client ์œ„์— ์„ ์–ธ
/// <reference types="vite/client" />

 

๐Ÿ’ก JSX ์ง€์›

๊ธฐ๋ณธ์ ์œผ๋กœ .jsx, .tsx ๋ฅผ Esbuild ๋กœ ์ปดํŒŒ์ผ๋ง ํ•ฉ๋‹ˆ๋‹ค.

์•„๋ž˜ 3๊ฐ€์ง€ ์˜ต์…˜์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, vite ์—์„œ๋งŒ ์ œ๊ณตํ•˜๋Š” jsxInject ๋„ ์‚ฌ์šฉํ•˜๋Šฅํ•ฉ๋‹ˆ๋‹ค.

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  esbuild: {
    jsxFactory: 'h',
    jsxFragment: 'Fragment',
    jsxInject: `import React from 'react'`,
  },
})

 

๐Ÿ’ก CSS

- .css ํŒŒ์ผ์€ HMR ์„ ์ง€์›ํ•˜๋ฉฐ, <style> ํƒœ๊ทธ๋กœ html ์— ์ฃผ์ž…๋ฉ๋‹ˆ๋‹ค.

- vite ๋Š” @import, url() ๊ตฌ๋ฌธ์„ postcss-import ๋ฅผ ์ด์šฉํ•ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ( process.pwd() ๋กœ ์น˜ํ™˜ํ•˜์—ฌ local ์— ์žˆ๋Š” ์—์…‹์„ ์ฐธ์กฐํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค)

- Esbuild ๋ฅผ ํ†ตํ•ด css ์ถ•์†Œ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

PostCSS ๊ธฐ๋ณธ ์ง€์›

ํ”„๋กœ์ ํŠธ์— postcss ์„ค์ •ํŒŒ์ผ์ด ์กด์žฌํ•œ๋‹ค๋ฉด, vite ๋ชจ๋“  css ํŒŒ์ผ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ ๋กœ css ์ตœ์ ํ™”๋Š” PostCSS ์ดํ›„์— ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค.

 

CSS Modules

.module.css ํ™•์žฅ์ž๋Š” css ๋ชจ๋“ˆ ๋กœ ์ทจ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

 

CSS ์ „์ฒ˜๋ฆฌ๊ธฐ ์ง€์›

.scss, .sass, .less ์™€ ๊ฐ™์€ css ์ „์ฒ˜๋ฆฌ๊ธฐ๋Š” ํŒจํ‚ค์ง€ ์„ค์น˜๋งŒ ํ•˜๋ฉด ๋ฐ”๋กœ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

vue ์˜ ๊ฒฝ์šฐ <style lang="sass"> ์ด๋Ÿฐ์‹์œผ๋กœ ์„ค์น˜ ํ›„ lang ๋งŒ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋ฐ”๋กœ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

npm add -D sass
npm add -D less
npm add -D stylus

 

ํŽ˜์ด์ง€์— CSS ์ฃผ์ž… ๋น„ํ™œ์„ฑํ™”

?inline ์ฟผ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด, html ์— <style> ๋กœ ์ฃผ์ž…๋˜์ง€ ์•Š๊ณ , import ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

import './styles/index.less?inline';

 

๐Ÿ’ก Static assets

์ •์  ์—์…‹์„ import ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์–ด๋–ป๊ฒŒ ๊ฐ€์ ธ์˜ฌ์ง€ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import imgUrl from './img.png'
document.getElementById('hero-img').src = imgUrl

// URL๋กœ ์—์…‹ ๊ฐ€์ ธ์˜ค๊ธฐ
import assetAsURL from './asset.js?url'

// String ํƒ€์ž…์œผ๋กœ ์—์…‹ ๊ฐ€์ ธ์˜ค๊ธฐ
import assetAsString from './shader.glsl?raw'

// ์›น ์›Œ์ปค ๊ฐ€์ ธ์˜ค๊ธฐ
import Worker from './worker.js?worker'

// Base64 ํฌ๋งท์˜ ๋ฌธ์ž์—ด ํ˜•ํƒœ๋กœ ์›น ์›Œ์ปค ๊ฐ€์ ธ์˜ค๊ธฐ
import InlineWorker from './worker.js?worker&inline'

 

webpack ์˜ file-loader ์™€ ๋น„์Šทํ•œ๋ฐ, vite ๋Š” ์ ˆ๋Œ€๊ฒฝ๋กœ์™€ ์ƒ๋Œ€๊ฒฝ๋กœ ๋ชจ๋‘ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋ฉฐ, ์ž๋™์œผ๋กœ ๋ถ„์„ํ•˜์—ฌ ๋ฒˆ๋“คํŒŒ์ผ์— ์˜ฌ๋ฐ”๋ฅธ ์œ„์น˜๋กœ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋‘˜๋‹ค ๊ฒฐ๊ตญ /assets/bg.png ๋กœ ๋ฒˆ๋“ค๋ง๋˜๊ณ  ๊ฐ’๋„ ์ ์ ˆํžˆ ๋ฐ”๋€๋‹ˆ๋‹ค.

<img src="./public/bg.png" alt="">
<img src="/bg.png" alt="">

 

- assetsInlineLimit ์˜ต์…˜์˜ ๊ฐ’๋ณด๋‹ค ์ž‘์€ ์—์…‹์˜ ๊ฒฝ์šฐ ์—์…‹์„ ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌํ•˜์ง€ ์•Š๊ณ , Base64 ํฌ๋ฉง์˜ ๋ฐ์ดํ„ฐ URL ๋ฌธ์ž์—ด๋กœ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.

- ๐Ÿ™ Typescript ์˜ ๊ฒฝ์šฐ ์ •์  ์—์…‹์„ import ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” `vite/client` ํƒ€์ž…์„ ์ถ”๊ฐ€ํ•ด์ค˜์•ผํ•ฉ๋‹ˆ๋‹ค.

- public ํด๋”์˜ ์—์…‹๋“ค์ด ๋ฒˆ๋“คํŒŒ์ผ์˜ ๋ฃจํŠธ๊ฒฝ๋กœ์— ๊ทธ๋Œ€๋กœ ๋ณต์‚ฌ๋˜๋ฉฐ, `publicDir` ์˜ต์…˜์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ๋Š” ํŽ˜์ด์ง€๋ณ„๋กœ, ํ˜น์€ ํƒ€ ์„œ๋น„์Šค์— ์ผ๋ถ€๋ถ„์œผ๋กœ ๋ฐฐํฌํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ( githubPages ... etc)

 

 

๐Ÿ’ก JSON

.json ์€ ๋ณ„๋„ ์ฒ˜๋ฆฌ์—†์ด import ๊ฐ€๋Šฅํ•˜๊ณ , ํ•„ํŠธ๋ฅผ ์ง€์ •ํ•ด ๊ฐ€์ ธ์˜ค๋ฉด ํŠธ๋ฆฌ์‰์ดํ‚น์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

// ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ
import json from './example.json'
// ํ•„๋“œ๋ฅผ ์ง€์ •ํ•ด ๊ฐ€์ ธ์˜ค๊ธฐ (ํŠธ๋ฆฌ ์…ฐ์ดํ‚น ๋ฉ๋‹ˆ๋‹ค.)
import { field } from './example.json'

 

๐Ÿ’ก ๋™์  import

์ข€๋” ๋””ํ…Œ์ผํ•œ ๊ธด์œผ์€ Glob Import ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ฐ„๋‹จํžˆ ๋™์  import ๋Š” ์ง๊ด€์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋งŒ, file ์˜ depth ๋Š” 1์ด ์ตœ๋Œ€๋ผ๋Š” ์ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด `foo/bar` ์™€๊ฐ™์ด 2 depth ๋ผ๋ฉด Glob Import ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

const module = await import(`./dir/${file}.js`)

 

๐Ÿ’ก Web Workers

์†Œ์Šค์ฝ”๋“œ ๋‚ด์˜ workder ํŒŒ์ผ์„ import ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

`src/worker.js`

const url = new URL('./worker.js', import.meta.url);
const worker = new Worker(url);

 

๐Ÿ› ๏ธ ๋นŒ๋“œ ์ตœ์ ํ™”

vite ๋Š” ์ถ”๊ฐ€์ ์ธ ์„ค์ • ์—†์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค์—์„œ ์ตœ์ ํ™”๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

 

css code splitting

- import ๋œ css ํŒŒ์ผ์€ ๋ถ„๋ฆฌ๋˜์–ด <link> ํƒœ๊ทธ๋กœ ์ฝ”๋“œ๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

- ๋งŒ์•ฝ ๋น„๋™๊ธฐ import ์— ํฌํ•จ๋œ css ๋ผ๋ฉด, css ๊ฐ€ ๋ชจ๋‘ ๊ณ„์‚ฐ๋œ ์ดํ›„์— ํ•ด๋‹น ํŒŒ์ผ์„ ๋ Œ๋”ํ•˜๋„๋ก ํ•˜์—ฌ, CSS ๊ฐ€ ๊นœ๋นก์ด๋Š” FOUCํ˜„์ƒ(Flash of unstyled content) ๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

 

๋น„๋™๊ธฐ import ์ตœ์ ํ™”

๋ถˆ๋Ÿฌ์˜ค๊ณ ์ž ํ•˜๋Š” ๋ชจ๋“ˆ์ด Dynamic Import ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด, ํ•ด๋‹น ๋ชจ๋“ˆ์ด ๋ถˆ๋Ÿฌ์˜ค๊ณ  ๋‚˜์„œ์•ผ, ํ•œ๋ฒˆ๋” ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ํ†ตํ•ด ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ ๋˜ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ์ด๋Š” ๋ถˆํ•„์š”ํ•œ ๋„คํŠธ์›Œํฌ ๋‚ญ๋น„์ด๋ฉฐ, vite ๋Š” Preload ์Šคํ…์„ ์ด์šฉํ•ด Dynamic Import ๊ตฌ๋ฌธ๋„ ์žฌ์ž‘์„ฑํ•˜์—ฌ ์ด๋Ÿฐ ๋น„๋™๊ธฐ Import ์‹œ์— ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ ํ•œ๋ฒˆ์— ๋ถˆ๋Ÿฌ์˜ค๋„๋ก ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

 

๐Ÿ’ก ์บ์‹ฑ

vite ๋Š” node_modules ๋ฅผ ์‚ฌ์ „๋ฒˆ๋“ค๋ง ํ•œ๋‹ค๊ณ  ํ–ˆ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๊ฐ๊ฐ์„ /node_modules/.vite ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์บ์‹œํ•˜๊ณ , ๊ฐœ๋ฐœ์„œ๋ฒ„์— ์ œ๊ณตํ•˜๊ณ ์žˆ์–ด์š”.

๊ฐœ๋ฐœ์‹œ ์บ์‹ฑ์€ http ํ—ค๋”์— max-age=31536000, immutable ์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๋‹ค์‹œ ๋‹ค์šด๋กœ๋“œ๋ฐ›์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ฉด ์บ์‹œ๋ฅผ ์œ ์ง€ํ•˜๋ฉด์„œ ๋น ๋ฅธ ๊ฐœ๋ฐœ์„œ๋ฒ„ ์†๋„๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

 

- package.lock.json ํŒŒ์ผ์ด ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒฝ์šฐ

- ํด๋” ์ˆ˜์ •์‹œ๊ฐ„์ด ๋ฐ”๋€Œ๋Š” ๊ฒฝ์šฐ

- vite.config.js ๊ฐ€ ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ

- NODE_ENV ๊ฐ€ ๋ณ€๊ฒจ๋  ๊ฒฝ์šฐ

 

์˜๋„์ ์œผ๋กœ ์บ์‹œ๋ฅผ ์ œ๊ฑฐํ•  ๊ฒฝ์šฐ๋Š” --force ์˜ต์…˜๊ณผ ํ•จ๊ป˜ ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์žฌ์‹œ์ž‘ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

๐Ÿ’ก ์ตœ์ข… ๋นŒ๋“œ

vite ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํƒ€ํ‚ทํ•˜๊ณ  ๋นŒ๋“œํ•ฉ๋‹ˆ๋‹ค.

ESM, ๋™์  import, import.meta ๋ฅผ ์ง€์›ํ•˜๋Š” ๋ธŒ๋ผ์šฐ์ €๋ฅผ ํƒ€ํ‚ทํ•จ์œผ๋กœ, es2015 ์ดํ•˜ ๋ฒ„์ „์„ ์ง€์›ํ•˜๋Š” ๋ฐ”๋ฒจ๊ณผ ๋‹ฌ๋ฆฌ ๊ทธ ์ด์ƒ๋งŒ์„ ์ง€์›ํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ฐ”๋ฒจ์ฒ˜๋Ÿผ es2015 ๋ฒ„์ „ ์ดํ•˜๋„ ์ง€์›ํ•˜๋„๋ก ๋นŒ๋“œํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด @vitejs/plugin-legacy ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

 

๋นŒ๋“œ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

๋นŒ๋“œ๋Š” Rollup ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ปค์Šคํ„ฐ๋งˆ์ด์ง• ํ•˜๊ธฐ์œ„ํ•ด์„œ build.rollupOptions ๋ฅผ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      // https://rollupjs.org/configuration-options/
    }
  }
})

 

๐Ÿ’ก ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชจ๋“œ

Rollup ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ตœ์ ํ™”๋œ ๋ฒˆ๋“ค๋ง ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ๋ผ์ด๋ธŒ์„œ๋ฒ„์˜ ๋ถ€์žฌ์™€ ๋”๋ถˆ์–ด์„œ ์‹ค์ œ๋กœ ์›น์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐœ๋ฐœํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ๋ณ„๋„์˜ ํ”„๋กœ์ ํŠธ ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ link ๋ฅผ ํ†ตํ•ด์„œ ๊ฐœ๋ฐœํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ด๋Š” ์ƒ๋‹นํžˆ ๋ฒˆ๊ฑฐ๋Ÿฌ์šฐ๋ฉฐ, vite ์—์„œ๋Š” ์›น๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ํƒ€ํ‚ท์œผ๋กœ ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ์„ค์ •์„ ํฌํ•จํ•˜๊ณ  ์žˆ์–ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

 

๋ฆฌ์•กํŠธ๊ธฐ๋ฐ˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค์ • ์˜ˆ์‹œ

build:{
  lib:{
      entry:'./src/lib/index.ts',
      name:'NiceUI',
      fileName:'index'
  },
    rollupOptions:{
        external:['react','react-dom'],
        output:{
            globals:{
                react:'React',
                'react-dom':'ReactDOM'
            }
        }
    }
}
//...
 plugins: [
    react(),
    dts({include:'src/lib/**/*'})
]

build ์˜ lib ์˜ต์…˜๊ณผ, rollupOptions ์œผ๋กœ ๋นŒ๋“œ์‹œ์— ๋ฒˆ๋“ค๋ง์—์„œ ์ œ์™ธํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‚ฌ์šฉ๋  ๊ณณ peerDependencies ๋ฅผ ์ ์ ˆํžˆ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋กœ ์ž‘์„ฑํ•œ๋‹ค๋ฉด dts() ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ถ”๊ฐ€ํ•˜๊ณ , include ์†์„ฑ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ฐœํ™˜๊ฒฝ ์ „์ฒด ํƒ€์ž…์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋„๋ก ํ•ด์ค๋‹ˆ๋‹ค.(์•„๋‹ˆ๋ฉด ์ง์ ‘ ์ž‘์„ฑํ•ด๋„ ๋˜๊ตฌ์š”)

 

๊ด€ํ–‰์ ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ชจ๋“ˆ์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์—”ํŠธ๋ฆฌํฌ์ธํŠธ๋ฅผ ํŽธํ•˜๊ฒŒ ํ•˜๋‚˜๋กœ ์žก๊ธฐ ์œ„ํ•ด์„œ index ํŒŒ์ผ์—์„œ ํ•„์š”ํ•œ ๋ชจ๋“ˆ์„ ๋ชจ๋‘ ๋ชจ์•„ ๋‹ค์‹œ export ํ•˜๋Š” ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

// src/lib/index.ts
export {default as NiceButton} from './NiceButton'

 

๊ทธ๋ฆฌ๊ณ  ํŒจํ‚ค์ง€๋กœ ๋ฐฐํฌํ•  ๋•Œ๋Š” package.json ์„ค์ •์„ ์ƒ์„ธํžˆ ํ•ด์ฃผ์…”์•ผํ•ฉ๋‹ˆ๋‹ค.

vite ๋Š” commonJS, ESM ๋ชจ๋“ˆ ๋‘๊ฐ€์ง€๋ฅผ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋‘ํŒŒ์ผ์„ exports ์— ์—ฐ๊ฒฐํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

// package.json
{
  "name": "NiceUI",
  "main": "./dist/index.mjs",
  "exports": {
    ".": {
      "import": "./dist/index.mjs",
      "require": "./dist/index.cjs"
    }
  }
}

 

๐Ÿ’ก ๋งŒ์•ฝ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐœ๋ฐœ์„ ํ•˜๋Š”๋ฐ, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋ผ๋ฉด rollup ์„ ์ง์ ‘ ์‚ฌ์šฉํ•˜์‹œ๋Š” ๊ฒƒ์ด ๊ถŒ์žฅ๋ฉ๋‹ˆ๋‹ค.

 

๐Ÿ’ก Env

ํ™˜๊ฒฝ๋ณ€์ˆ˜๋Š” dotnev ๋ฅผ ํ™•์žฅํ•˜์—ฌ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ๋กœ ์ œ๊ณตํ•˜๊ณ ์žˆ์Šต๋‹ˆ๋‹ค.

.env                # ๋ชจ๋“  ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ๋  ํ™˜๊ฒฝ ๋ณ€์ˆ˜
.env.local          # ๋ชจ๋“  ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉ๋˜๋‚˜, ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉ๋ (Git์— ์˜ํ•ด ๋ฌด์‹œ๋ ) ํ™˜๊ฒฝ ๋ณ€์ˆ˜
.env.[mode]         # ํŠน์ • ๋ชจ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉ๋  ํ™˜๊ฒฝ ๋ณ€์ˆ˜
.env.[mode].local   # ํŠน์ • ๋ชจ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋‚˜, ๋กœ์ปฌ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ๋งŒ ์‚ฌ์šฉ๋ (Git์— ์˜ํ•ด ๋ฌด์‹œ๋ ) ํ™˜๊ฒฝ ๋ณ€์ˆ˜

 

env ์ปค์Šคํ…€ ํƒ€์ž… ์ง€์ •

// src/env.d.ts

interface ImportMetaEnv {
    readonly ๋ณ€์ˆ˜๋ช…: string
}

interface ImportMeta {
    readonly env: ImportMetaEnv
}

 

html ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ

%๋ณ€์ˆ˜๋ช…%

<h1>%VITE_HOST%</h1>

 

vite ๋ชจ๋“œ์— ๋”ฐ๋ผ ์ ์ ˆํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

yarn vite : .env.development

yarn build : .env.production

yarn ** --mode ๋ชจ๋“œ : ๋ชจ๋“œ ์ง์ ‘ ์ง€์ •

 

๐Ÿ”Œ ํ”Œ๋Ÿฌ๊ทธ์ธ

vite ๋Š” Rollup ์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์„ ์‚ฌ์šฉํ•˜์—ฌ, ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.

โœจ ํ˜ธํ™˜๋˜๋Š” Rollup ํ”Œ๋Ÿฌ๊ทธ์ธ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค(๋‹ค๋งŒ ๋Œ€๋ถ€๋ถ„ vite ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ง€์›ํ•˜๊ณ  ์žˆ์œผ๋‹ˆ ๋จผ์ € ํ™•์ธํ•ด๋ณด๊ณ  Rollup ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ฐพ์•„๋ณด์„ธ์š”)

๊ณต์‹ ํ”Œ๋Ÿฌ๊ทธ์ธ

์ปค๋ฎค๋‹ˆํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ

ํ˜ธํ™˜๋˜๋Š” Rollup ํ”Œ๋Ÿฌ๊ทธ์ธ

์ด์™ธ์—๋„ npm ์— `vite-plugin`, `rollup-plugin` ์œผ๋กœ ๊ฒ€์ƒ‰ํ•ด์„œ ์ฐพ์„ ์ˆ˜ ๋„์žˆ์Šต๋‹ˆ๋‹ค.

 

ํ”Œ๋Ÿฌ๊ทธ์ธ ์ˆœ์„œ

1. ๋ณ„์นญ

2. enforce: 'pre'

3. vite core

4. enforce ๊ฐ’์ด ์—†๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ

5. build ํ”Œ๋Ÿฌ๊ทธ์ธ

6. enforce : 'post'

7. ๋นŒ๋“œ ํ›„ ์‹คํ–‰๋˜๋Š” vite ํ”Œ๋Ÿฌ๊ทธ์ธ (minify, manifest, reporting)

 

Rollup ํ”Œ๋Ÿฌ๊ทธ์ธ ํ˜ธํ™˜

์ƒ๋‹นํ•œ ์ˆ˜์˜ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋“ค์ด vite ์™€ ํ˜ธํ™˜๋˜์ง€๋งŒ, ๋‹ค ๊ทธ๋Ÿฐ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค.

Rollup ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ํ›…์˜ ๊ฒฝ์šฐ์— ๋ฒˆ๋“ค๋˜์ง€ ์•Š์€ ๊ฐœ๋ฐœ์„œ๋ฒ„์—์„œ๋Š” ์˜๋ฏธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์—, ๋ชจ๋‘ vite ์™€ ํ˜ธํ™˜๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

 

๋‹ค์Œ ์กฐ๊ฑด์— ๋งŒ์กฑํ•œ๋‹ค๋ฉด vite ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

- moduleParsed ํ›…์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

- ๋ฒˆ๋“ค๋‹จ๊ณ„์™ธ ํ›…๊ณผ ๋ฒˆ๋“ค ์ดํ›„ ์ถœ๋ ฅ ๋‹จ๊ณ„์˜ ํ›… ์‚ฌ์ด์˜ ๊ฐ•๋ ฅํ•œ ๊ฒฐํ•ฉ์ด ์—†์–ด์•ผํ•œ๋‹ค.

 

์œ„ ์กฐ๊ฑด์„ ์ถฉ์กฑํ•˜์ง€ ์•Š์•„์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์ง€๋งŒ, ๋นŒ๋“œ๋‹จ๊ณ„์—์„œ ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ํ”Œ๋Ÿฌ๊ทธ์ธ ์‚ฌ์šฉ์„ ์ปค์Šคํ…€ํ•ด์„œ ๋ณด๊ฐ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์ด enforce ์™€ apply ๋ฅผ ์กฐ์ •ํ•˜์—ฌ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์–ธ์ œ ์ ์šฉ๋ ์ง€๋ฅผ ์ˆ˜์ •ํ•ด ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

export default defineConfig({
  plugins: [
    {
      ...example(),
      enforce: 'post',
      apply: 'build'
    }
  ]
})

 

๋งˆ๋ฌด๋ฆฌ

vite ๊ณต์‹๋ฌธ์„œ ์ •๋…์„ ํ•œ 4๋ฒˆ์งธ ์ •๋„ํ•˜๋Š” ์‹œ์ ์— ์ •๋ฆฌ๋ฅผ ํ•ด๋ณด๊ฒŒ ๋˜์—ˆ๋„ค์š”.

๊ณ„๊ธฐ๊ฐ€ ๋œ๊ฒƒ์ด webpack ์ด ํŽธํ•ด์ง€๊ธด ํ–ˆ์ง€๋งŒ, ํ”„๋ก ํŠธ์—”๋“œ๊ฐœ๋ฐœ ํ• ๋•Œ ๊ฑฐ์˜ ํ•„์ˆ˜์ ์œผ๋กœ ํ•ด์•„ํ•˜๋Š” ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ ๋Ÿ‰์ด ๊ฝค๋‚˜ ๋งŽ๋”๋ผ๊ตฌ์š”.

์•„๋ž˜๋Š” ๋ฆฌ์•กํŠธ ํ™˜๊ฒฝ ๊ตฌ์ถ•ํ•œ๊ฑด๋ฐ, ์ด์ œ๋Š” ๋„ˆ๋ฌด ๋‹น์—ฐํ•ด์ง„ ๊ฒƒ๋“ค์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋Š๊ปด์ ธ์„œ ํ”ผ๋กœ๊ฐ์ด ๋“ค๋”๋ผ๊ตฌ์š”

const path = require('path');
const { EsbuildPlugin } = require('esbuild-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyPlugin = require('copy-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');

const isDevelopment = process.env.NODE_ENV !== 'production';

module.exports = {
  mode: isDevelopment ? 'development' : 'production',
  entry: path.resolve(__dirname, 'src', 'index.tsx'),
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.js',
  },
  module: {
    rules: [
      {
        test: /\.[jt]sx?$/,
        loader: 'esbuild-loader',
        options: {
          target: 'es2015',
        },
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },
    ],
  },
  optimization: {
    minimizer: [
      new EsbuildPlugin({
        target: 'es2015',
        css: true,
      }),
    ],
  },
  devServer: {
    port: 3000,
    static: {
      directory: path.resolve(__dirname, 'public'),
    },
    hot: true,
    client: {
      logging: 'none',
    },
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'index.html'),
    }),
    new MiniCssExtractPlugin(),
    new CopyPlugin({
      patterns: [{ from: 'public', to: '.' }],
    }),
    new ForkTsCheckerWebpackPlugin(),
    new webpack.ProvidePlugin({
      React: 'react',
    }),
    isDevelopment && new ReactRefreshWebpackPlugin(),
  ],
  resolve: {
    extensions: ['.js', '.jsx', '.ts', '.tsx'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
    },
  },
};

 

๋ญ.. ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด๋†“๊ณ , ๋ณต์‚ฌํ•ด๊ฐ€๋ฉด์„œ ์‚ฌ์šฉํ•ด๋„ ๋˜์ง€๋งŒ ์ด๋ฏธ ์ข‹์€ ๋Œ€์•ˆ๋“ค์ด ๋‚˜์™€์žˆ๋Š”๋ฐ ๊ตณ์ด ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์žˆ๋‚˜ ์‹ถ์€์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

Rollup ์˜ ์™„๋ฒฝํ•œ commonJS, ESM, UMD ์ง€์› + ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœํ™˜๊ฒฝ ํˆด์ธ vite ์˜ ์กฐํ•ฉ์€ ๊ฐœ๋ฐœ๊ฒฝํ—˜์ด ๋„ˆ๋ฌด ์ข‹์•˜์Šต๋‹ˆ๋‹ค. 

๊ทธ๋ ‡๋‹ค๊ณ  webpack ์„ ๊ฑด๋„ˆ๋„์–ด๋„ ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์ง„ ์•Š์Šต๋‹ˆ๋‹ค. nextjs ์™€ ๊ฐ™์ด ์ ์œ ์œจ 1์œ„ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” ์—ฌ์ „ํžˆ webpack์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋‹ˆ๊นŒ์š”. ์ปค์Šคํ…€ ํ•  ์ผ์ด ์ข…์ข… ๋ฐœ์ƒํ•˜๊ฑฐ๋“ ์š”.

 

webpack, babel ๋„ ๊ฐ๊ฐ 6~7 ๋ฒˆ์”ฉ์€ ์ •๋…ํ•˜๊ณ , ์—ฐ์Šตํ–ˆ๋˜๊ฑฐ ๊ฐ™์•„์š”.

์ฐธ ํ•˜๋‚˜๋งŒ ๋ฐฐ์›Œ์„œ ๋๊นŒ์ง€ ์“ด๋‹ค๋Š”๊ฑด ์—†๋Š”๊ฑฐ ๊ฐ™๊ธดํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ์ƒํƒœ๊ณ„๋Š” ํ•ญ์ƒ ์•ž์ „์˜ ํ•ด๊ฒฐ์ฑ…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋” ๋‚˜์€ ํ•ด๊ฒฐ์ฑ…์„ ๋งŒ๋“ค์–ด๋‚ด๊ณ , ์–ด๋–จ ๋•Œ๋Š” ์•„์–˜ ๋‹ค๋ฅธ ์ ‘๊ทผ๋ฐฉ์‹์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•ด ์ƒˆ๋กœ์šด ์˜์—ญ์„ ๋ฐ›์•„๋“ค์–ด์•ผ ํ•˜๊ธฐ๋„ ํ•˜์ง€์š”.

 

vite ๊ณต์‹๋ฌธ์„œ๋Š” ๋„ˆ~~๋ฌด๋‚˜ ์ž˜์ •๋ฆฌ๋˜์–ด์žˆ์œผ๋‹ˆ, ํ•œ๋ฒˆ ๋ณด์‹œ๋Š” ๊ฑธ ์ถ”์ฒœ๋“œ๋ฆฌ๊ณ , ์ €๋Š” ๊ทธ์ค‘์—์„œ ํ•ต์‹ฌ + ๊ฐœ์ธ์  ๊ฒฌํ•ด + ์ดํ•ด๋ฅผ ๋•๊ธฐ์œ„ํ•œ ์ฒจ์–ธ ์œผ๋กœ ๊ธ€์„ ์ž‘์„ฑํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๋ฐ˜์‘ํ˜•