๐ง๐ญ๏ธ 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 ๊ณต์๋ฌธ์๋ ๋~~๋ฌด๋ ์์ ๋ฆฌ๋์ด์์ผ๋, ํ๋ฒ ๋ณด์๋ ๊ฑธ ์ถ์ฒ๋๋ฆฌ๊ณ , ์ ๋ ๊ทธ์ค์์ ํต์ฌ + ๊ฐ์ธ์ ๊ฒฌํด + ์ดํด๋ฅผ ๋๊ธฐ์ํ ์ฒจ์ธ ์ผ๋ก ๊ธ์ ์์ฑํด ๋ณด์์ต๋๋ค.
'FE > vite' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
vite ํ๊ฒฝ๋ณ์ (0) | 2023.01.13 |
---|---|
vite ๋น๋ํ๊ธฐ (0) | 2023.01.09 |
vite ๊ฐ CSS, Static Assets, JSON, Dynamic Imports๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฐฉ๋ฒ (0) | 2023.01.09 |
vite์ module ์ฒ๋ฆฌ์ typescript ์ค์ ์ดํด๋ณด๊ธฐ (0) | 2023.01.09 |
Vite๋ก ๊ฐ๋ฐํ๊ฒฝ ๋ง๋ค๊ธฐ (0) | 2023.01.08 |