์๋ก
๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ๋ฅผ the-NDD organization์ผ๋ก ์ด์ ํ๊ฒ ๋๋ฉด์ ๊ธฐ์กด Webpack์ ์ฌ์ฉํ๋ ํ๋ก์ ํธ๋ฅผ Vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ์ต๋๋ค. ๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ ์ด๊ธฐ ์ธํ ์์ ์นํฉ์ ์ ํํ ์ฃผ๋ ์ด์ ๋ ํ์ต ๊ฒฝํ์ ์ค์ํ๊ฒ ์ฌ๊ฒผ๊ธฐ ๋๋ฌธ์ด์์ต๋๋ค. ๋ถ์คํธ์บ ํ์์ 6์ฃผ๊ฐ์ ํ๋ก์ ํธ ๊ธฐ๊ฐ๋์ ์นํฉ์ ํตํด ์ง์ ํ๋ก์ ํธ๋ฅผ ํ๋์ฉ ์ธํ ํด๋ณด๋ฉด์ CRA๋ง ์ฌ์ฉํ๋ค๋ฉด ์์ง ๋ชปํ์ ๊ฒ๋ค์ ๋ํด ํ์ตํด๋ดค์ต๋๋ค. ์์ง ์นํฉ์ ๋ํด ๋ชจ๋ฅด๋ ๋ถ๋ถ์ด ๋ง๊ฒ ์ง๋ง, ๊ธฐ์ด์ ์ธ ๋ถ๋ถ์ ๋ํด์๋ ์ถฉ๋ถํ ํ์ตํ๋ค๊ณ ํ๋จํ๊ณ , ์ด์ ๋ ๋ ๋น ๋ฅด๊ณ ํธ๋ฆฌํ vite๋ฅผ ์ฌ์ฉํ๊ธฐ๋ก ํ์๋ค๊ณผ ์ด์ผ๊ธฐ๋ฅผ ๋๋ด์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ ์งํํ๋ ๊ณผ์ ๋ํ ํ๋์ ํ์ต ๊ฒฝํ์ด ๋ ์ ์๋ค๊ณ ํ๋จํด์ vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ์ ์งํํ๊ฒ ๋์์ต๋๋ค.
vite๋ ์ Webpack๋ณด๋ค ๋น ๋ฅผ๊น?
vite ๊ฐ๋ฐ ์๋ฒ ๋น๋ ์๋๊ฐ ๋น ๋ฅธ ์ด์
vite์ ๊ฐ๋ฐ ์๋ฒ ๋น๋ ์๋๋ Webpack์ด๋ Parcel๊ณผ ๊ฐ์ ๊ธฐ์กด ๋ฒ๋ค๋ฌ๋ณด๋ค 10๋ฐฐ~100๋ฐฐ ์ ๋ ๋น ๋ฅธ ์๋๋ฅผ ์ ๊ณตํฉ๋๋ค. ๊ทธ ์ด์ ๋ vite๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ชจ๋์ dependencies์ source code ๋ ๊ฐ์ง ์นดํ ๊ณ ๋ฆฌ๋ก ๋๋์ด์ ๋น๋ํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
dependencies
dependencies์ ๊ฒฝ์ฐ source code์ ๋นํด ์์ฃผ ๋ณ๊ฒฝ๋์ง ์์ง๋ง ์๋ง์ ๋ชจ๋ ์ข ์์ฑ์ด ํฌํจ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ง์ ์ฒ๋ฆฌ ์๊ฐ์ด ์์๋ฉ๋๋ค. vite๋ ์ด๋ฌํ dependencies๋ค์ go์ธ์ด๋ก ์์ฑ๋ esbuild๋ฅผ ์ฌ์ฉํด ์ฌ์ ๋ฒ๋ค๋งํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ๋ฒ๋ค๋ฌ๋ณด๋ค ๋น ๋ฅธ ๋ฒ๋ค๋ง ์๊ฐ์ ๋ณด์ฌ์ค๋๋ค.
source code
vite๋ ๊ฐ๋ฐ ์๋ฒ์์ Native ESM์ ์ฌ์ฉํด์ ๋ชจ๋์ ๋ก๋ํฉ๋๋ค. ๋ฐ๋ผ์ ์์ค ์ฝ๋๊ฐ ๋ณ๊ฒฝ ๋์์ ๋ ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์
์ ๋ค์ ๋น๋ํ๋ ๋์ ๋ณ๊ฒฝ๋ ๋ชจ๋๋ง ๋น ๋ฅด๊ฒ ์
๋ฐ์ดํธํฉ๋๋ค.

Native ESM์ด๋? Native ESM์ ์ฌ์ฉํ๋ฉด ๋ณ๋์ ๋ฒ๋ค๋ฌ ์์ด ๋ฐ๋๋ผ JS์ ๋ธ๋ผ์ฐ์ ๋ง์ผ๋ก ๋ชจ๋ import๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์ฌ์ฉ ๋ฐฉ๋ฒ
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ESM Example</title>
</head>
<body>
<script type="module" src="main.js"></script>
</body>
</html>html ํ์ผ์์ script ํ๊ทธ๋ก js ํ์ผ์ ๋ถ๋ฌ์ฌ ๋ type์ module๋ก ์ค์ ํ๋ฉด Native ESM์ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋ชจ๋์ ๋ถ๋ฌ์ค๊ณ ๋ด๋ณด๋ด๋ ๋ฌธ๋ฒ์ ๋ฒ๋ค๋ฌ๋ฅผ ์ฌ์ฉํ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก import/export๋ฅผ ์ฌ์ฉํฉ๋๋ค.
Webpack๊ณผ Vite์ HMR
Native ESM์ ์ฌ์ฉํ๋ vite์ ํน์ง ๋๋ถ์ vite๋ ๋ ๋น ๋ฅธ HMR์ ์ ๊ณตํฉ๋๋ค. Webpack์ HMR์ ์ฝ๋์ ๋ณ๊ฒฝ ์ฌํญ์ด ์์ ๋ ์ ์ฒด ์์กด์ฑ ํธ๋ฆฌ๋ฅผ ์ฌ๊ตฌ์ฑํ๊ณ , ๊ฐํน ์ ์ฒด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ค์ ๋ฒ๋ค๋งํ๊ธฐ๋ ํฉ๋๋ค. ๋ฐ๋ผ์ ๊ท๋ชจ๊ฐ ํฐ ํ๋ก์ ํธ์ ๊ฒฝ์ฐ HMR์ ๊ฐฑ์ ์๊ฐ์ด ์ง์ฐ๋ฉ๋๋ค. ํ์ง๋ง vite๋ ESM์ ์ฌ์ฉํ HMR์ ์ง์ํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๊ฐ ์์ ๋๋ฉด ํด๋น ๋ถ๋ถ๊ณผ ๊ด๋ จ๋ ๋ชจ๋๋ง ๊ต์ฒด๋์ด ๋ธ๋ผ์ฐ์ ์ ์ ๋ฌํฉ๋๋ค. ๋๋ฌธ์ ํ๋ก์ ํธ์ ์ฌ์ด์ฆ๊ฐ ์ปค์ ธ๋ HMR ๊ฐฑ์ ์๊ฐ์๋ ์ํฅ์ ๋ผ์น์ง ์์ต๋๋ค.
webpack์์ vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๊ธฐ
์์ ๊ฐ์ ์ด์ ๋ก ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋น ๋ฅธ ๋น๋ ์๋๋ฅผ ์ํด ๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ๋ฅผ webpack์์ vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค. webpack์์ vite๋ก ๋ฒ๋ค๋ฌ๋ฅผ ๊ต์ฒดํ๊ธฐ ์ํด ๋ค์๊ณผ ๊ฐ์ ๊ณผ์ ์ ๊ฑฐ์ณค์ต๋๋ค.
1. ์๋ก์ด vite ํ๋ก์ ํธ ์์ฑ
yarn create vite gomterview-fe --template react-tsvite์ ํ์ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ์ ์ฌ์ฉํด์ ์๋ก์ด vite ํ๋ก์ ํธ๋ฅผ ์์ฑํ์ต๋๋ค. ๊ธฐ์กด ํ๋ก์ ํธ์์ ๋ฒ๋ค๋ฌ๋ง ๋ฐ๊พธ์ง ์๊ณ ์์ ์๋ก์ด ํ๋ก์ ํธ๋ฅผ ๋ง๋ ์ด์ ๋ ๋ง์ด๊ทธ๋ ์ด์ ์ ์งํํ๋ค๊ฐ ๋ฌธ์ ๊ฐ ์๊ฒผ์ ๋ ๊ธฐ์กด ํ๋ก์ ํธ ์ฝ๋์ ๋น๊ตํด๋ณด๋ฉฐ ํธ๋ฌ๋ธ ์ํ ์ ๋ ๋น ๋ฅด๊ฒ ํ ์ ์์ ๊ฒ์ด๋ผ๊ณ ํ๋จํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
2. ์ค์ ํ์ผ๊ณผ ํจํค์ง ํ์ผ์ ์ด๋
.eslintrc.json, .prettierrc.json, tsconfig.json, vite.config.ts๋ฑ์ ์ค์ ๊ณผ ๊ด๋ จ๋ ํ์ผ์ ์ด๋์ํจ ํ ํ๋ก์ ํธ๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋์ง ํ
์คํธํ์ต๋๋ค.
eslint ์ค์ ์ฎ๊ธฐ๊ธฐ
vite ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋ฉด cjs ํ์ฅ์์ eslint ์ค์ ํ์ผ์ด ์์ฑ๋ฉ๋๋ค. webpack์ ์ฌ์ฉํ๋ ๊ธฐ์กด ๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ๋ json ํ์ฅ์์ eslint ์ค์ ํ์ผ์ ์ฌ์ฉํ๊ณ ์์๊ธฐ ๋๋ฌธ์ cjs์์ json์ผ๋ก ํ์ฅ์๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค.
{
...
"ignorePatterns": ["webpack.config.js"] -> ["vite.config.ts"],
...
}.eslintrc.json ํ์ผ ๋ด์ฉ์ ignorePatterns ๋ถ๋ถ์ ์ ์ธํ๊ณค ๋ชจ๋ ๋์ผํ ์ค์ ์ ์ฌ์ฉํ์ต๋๋ค. ignorePatterns์ eslint๊ฐ ๊ฒ์ฌํ์ง ์์ ํ์ผ์ ๋ํด ์ง์ ํ๋ ์ค์ ์ ๋๋ค. ๋ฒ๋ค๋ฌ์ ์ค์ ํ์ผ์ eslint ๊ฒ์ฌ์์ ์ ์ธ์ํจ ์ด์ ๋ ์ค์ ํ์ผ์ ์ฝ๋๊ฐ ํ๋ก์ ํธ์ eslint ๊ท์น๊ณผ ๋ง์ง ์๋ ๋ถ๋ถ์ด ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.
tsconfig.json ์ค์ ์ฎ๊ธฐ๊ธฐ
vite ํ๋ก์ ํธ ์ด๊ธฐ์ค์ ์๋ tsconfig.json, tsconfig.node.json์ด๋ ๊ฒ ๋ ๊ฐ์ง ์ค์ ์ ํ์
์คํฌ๋ฆฝํธ ์ค์ ํ์ผ์ด ์กด์ฌํฉ๋๋ค. ๊ทธ ์ด์ ๋ node.js ํ๊ฒฝ์์ ์คํํ ๋์ ๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ์คํํ ๋์ ์ค์ ์ ๋ถ๋ฆฌํ๊ธฐ ์ํจ์
๋๋ค. (javascript - Vite๊ฐ tsconfig.json๊ณผ tsconfig.node.json์ด๋ผ๋ ๋ ๊ฐ์ TypeScript ๊ตฌ์ฑ ํ์ผ์ ์์ฑํ๋ ์ด์ ๋ ๋ฌด์์
๋๊น? - ์คํ ์ค๋ฒํ๋ก)
๋ง์ฝ ๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ๋ฅผ ์๋ฒ์ฌ์ด๋ ๋๋๋ง์ผ๋ก ๋ณ๊ฒฝํ ๊ฒ์ ์ผ๋ํด ๋๊ณ ์๋ค๋ฉด tsconfig.node.json ํ์ผ์ ์ ์งํ๊ฒ ์ง๋ง, ๊ทธ๋ฐ ๊ณํ์ ์๊ธฐ ๋๋ฌธ์ tsconfig.json๊ณผ tsconfig.node.json์ ํ๋์ ํ์ผ๋ก ํฉ์ณค์ต๋๋ค.
{
"compilerOptions": {
"target": "ES2015", // ๊ฒฐ๊ณผ ํ์ผ ํ์
"module": "es2020", // module ํ์
"resolveJsonModule": true,
"esModuleInterop": true, // import์ namespace alias ๊ฐ๋ฅ
"moduleResolution": "bundler",
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"strict": true,
"noImplicitAny": true,
"baseUrl": ".",
"skipLibCheck": true,
"paths": {
"@common/*": ["./src/components/common/*"],
"@foundation/*": ["./src/components/foundation/*"],
"@components/*": ["./src/components/*"],
"@page/*": ["./src/page/*"],
"@constants/*": ["./src/constants/*"],
"@styles/*": ["./src/styles/*"],
"@assets/*": ["./src/assets/*"],
"@atoms/*": ["./src/atoms/*"],
"@hooks/*": ["./src/hooks/*"],
"@routes/*": ["./src/routes/*"],
"@/*": ["./src/*"]
}
},
"include": ["src"]
}vite.config.ts ์ค์ ํ๊ธฐ
๊ธฐ์กด ์นํฉ์ ์ฌ์ฉํ๋ ํ๋ก์ ํธ์์๋ ์ด๋ฏธ์ง ํ์ผ์ ์ํ file-loader, public Dir๋ฅผ ์ํ CopyPlugin ๋ฑ ๋ค์ํ ์ค์ ๋ค์ ์ง์ ์ธํ
ํด์ผ ํ์ต๋๋ค. ํ์ง๋ง vite์์๋ ์ด์ ๊ฐ์ ์ค์ ์ ์๋์ผ๋ก ํด์ฃผ๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฐ ํ๊ฒฝ ์คํ์ ์ํ dev server๋ง ์ฎ๊ฒจ์ฃผ์์ต๋๋ค.
webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack');
const CopyPlugin = require('copy-webpack-plugin');
const Dotenv = require('dotenv-webpack');
module.exports = (env) => {
const envMode = {
production: '.env.production',
development: '.env.development',
local: '.env.local',
};
const envPath = envMode[env.mode];
return {
mode: process.env.production === 'true' ? 'production' : 'development',
devtool: process.env.production === 'true' ? 'hidden-source-map' : 'eval',
entry: './src/index.tsx',
output: {
publicPath: '/',
path: path.resolve(__dirname, 'dist'),
filename: '[hash].js',
clean: true,
},
devServer: {
historyApiFallback: true,
port: 3000,
hot: true,
headers: {
'Cross-Origin-Opener-Policy': 'same-origin',
'Cross-Origin-Embedder-Policy': 'require-corp',
},
static: path.resolve(__dirname, 'dist'),
proxy: {
'/api': {
target: 'https://dev.gomterview.com',
changeOrigin: true,
},
},
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
alias: {
// src ํด๋๋ฅผ '@' ๋ณ์นญ์ผ๋ก ์ค์
'@': path.resolve(__dirname, 'src/'),
'@components': path.resolve(__dirname, 'src/components/'),
'@common': path.resolve(__dirname, 'src/components/common/'),
'@foundation': path.resolve(__dirname, 'src/components/foundation/'),
'@page': path.resolve(__dirname, 'src/page/'),
'@constants': path.resolve(__dirname, 'src/constants/'),
'@styles': path.resolve(__dirname, 'src/styles/'),
'@assets': path.resolve(__dirname, 'src/assets/'),
'@atoms': path.resolve(__dirname, 'src/atoms/'),
'@hooks': path.resolve(__dirname, 'src/hooks/'),
'@routes': path.resolve(__dirname, 'src/routes/'),
},
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
filename: 'index.html',
favicon: './public/favicon.ico',
}),
new webpack.HotModuleReplacementPlugin(),
new CopyPlugin({
patterns: [
{ from: 'public/mockServiceWorker.js', to: '' },
{ from: 'public/_headers', to: '' },
],
}),
new Dotenv({
path: envPath,
}),
],
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.(png|jpe?g|gif)$/i,
loader: 'file-loader',
options: {
outputPath: 'assets/images',
},
},
],
},
ignoreWarnings: [/Critical dependency:/],
};
};vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'@common': path.resolve(__dirname, './src/components/common'),
'@foundation': path.resolve(__dirname, './src/components/foundation'),
'@components': path.resolve(__dirname, './src/components'),
'@page': path.resolve(__dirname, './src/page'),
'@constants': path.resolve(__dirname, './src/constants'),
'@styles': path.resolve(__dirname, './src/styles'),
'@assets': path.resolve(__dirname, './src/assets'),
'@atoms': path.resolve(__dirname, './src/atoms'),
'@hooks': path.resolve(__dirname, './src/hooks'),
'@routes': path.resolve(__dirname, './src/routes'),
'@': path.resolve(__dirname, './src'),
},
},
optimizeDeps: {
exclude: ['@ffmpeg/ffmpeg', '@ffmpeg/util'],
},
server: {
port: 3000,
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
},
proxy: {
'/api': {
target: 'https://dev.gomterview.com',
changeOrigin: true,
},
},
},
plugins: [react()],
});์์ ๊ฐ์ด ์ค์ ํ์ผ์ ๋ชจ๋ ์ด๋์ํจ ํ ํ๋ก์ ํธ ๋น๋๊ฐ ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ๊ณ ๋ค์ ๋จ๊ณ๋ก ๋์ด๊ฐ์ต๋๋ค.
3. ์ฝ๋ ํ์ผ ์ด๋
src ํ์ผ์ ์ ๋ถ ๋ณต์ฌํด์ ์๋ก์ด vite ํ๋ก์ ํธ๋ก ์ฎ๊ฒผ์ต๋๋ค. ์ฌ๊ธฐ์ ์ ์ํ ์ ์ webpack์ ์ฌ์ฉํ ํ๋ก์ ํธ๋ public ๋๋ ํฐ๋ฆฌ ์์ index.html ํ์ผ์ด ์กด์ฌํ๋ค๋ฉด, vite ํ๋ก์ ํธ์์๋ ํ๋ก์ ํธ์ root ๋๋ ํฐ๋ฆฌ ์์ index.html์ด ์กด์ฌํ๋ ๊ฒ ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ vite ํ๋ก์ ํธ์ ์ง์ ์ ์ index.ts๊ฐ ์๋ main.ts๋ก ๋์ด์์ผ๋ฏ๋ก ์ด๋ฅผ index.ts๋ก ์์ ํ ํ index.html์ ์๋ script์ ์ฃผ์๋ ๋ณ๊ฒฝํด์ฃผ์์ต๋๋ค.
4. ๋ณ๊ฒฝ์ด ํ์ํ ์ฝ๋ ์์
env import ๋ฐฉ์ ์์
webpack ํ๋ก์ ํธ์์๋ process.env.[env ๋ณ์๋ช
] ํ์์ผ๋ก ํ๊ฒฝ๋ณ์ ํ์ผ์ ๋ด์ฉ์ ๊ฐ์ ธ์ต๋๋ค.
ํ์ง๋ง vite๋ import.meta.env.[env ๋ณ์๋ช
] ํ์์ผ๋ก ํ๊ฒฝ๋ณ์๋ฅผ ๊ฐ์ ธ์์ผํฉ๋๋ค. ๋ฐ๋ผ์ ์ด์ ๋ง๊ฒ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ต๋๋ค.
env ๋ณ์๋ช ์์
vite์์๋ ์ผ๋ฐ ํ๊ฒฝ๋ณ์์ ๊ตฌ๋ถ์ ์ํด ํ๊ฒฝ๋ณ์ ์์ VITE_๋ผ๋ ์ ๋์ฌ๋ฅผ ๋ถ์ฌ์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ ํ๊ฒฝ๋ณ์ ์ด๋ฆ๋ ์์ ํ์ต๋๋ค.
๋ง์ด๊ทธ๋ ์ด์ ํ๋ฉด์ ๊ฒช์ ์ด์
์ ์ฒด์ ์ธ ๋ง์ด๊ทธ๋ ์ด์ ๊ณผ์ ์ ์๊ฐ๋ณด๋ค ์ํํ๊ฒ ์งํ๋์๋๋ฐ์. ํ์ง๋ง ์๊ฐ์ง๋ ๋ชปํ ffmpeg ๋ชจ๋์์ ์ด์๊ฐ ๋ฐ์ํด์ ์ด๋ฅผ ํด๊ฒฐํ๋๋ฐ ๊ฐ์ฅ ๋ง์ ์๊ฐ์ ํฌ์ํ์ต๋๋ค.
ffmpeg ๋ชจ๋์ด ๋ก๋๋์ง ์์
๊ณฐํฐ๋ทฐ ์๋น์ค์์๋ ์ฌํ๋ฆฌ ์ง์์ ์ํด webm์ผ๋ก ์ดฌ์๋๋ ์์์ ๋ชจ๋ mp4๋ก ์ธ์ฝ๋ฉํ๊ณ ์์ต๋๋ค.
์ด๋ฅผ ์ํด ffmpeg์ ์น ์ด์
๋ธ๋ฆฌ ๋ฒ์ ์ธ ffmpeg.wasm์ ์ฌ์ฉํ๊ณ ์๋๋ฐ์. vite๋ก ๋ง์ด๊ทธ๋ ์ด์
์ ์งํํ ํ ffmpeg ๋ชจ๋์ด ์ ์์ ์ผ๋ก ๋ค์ด๋ก๋๋ ์ธ์ฝ๋ฉ์ด ์ํ๋์ง ์๋๋ค๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค.

๊ฐ์ฅ ๋ง๋งํ๋ ์ ์ ๋ก์ง์ด ์ ์์ ์ผ๋ก ์คํ๋์ง ์๋๋ฐ ffmpeg์์ ์๋ฌด๋ฐ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์์ฃผ์ง ์๋๋ค๋ ๊ฒ ์
๋๋ค. ๊ทธ๋์ ์ด์ฉ ์ ์์ด ๋ชจ๋์ ๋ก๋ํ๊ณ ์ธ์ฝ๋ฉ์ ์ํํ๋ ํจ์์์ ํ์ค ๋จ์๋ก ๋ก๊ทธ๋ฅผ ์ฐ์ด๋ณด๋ฉฐ ์ด๋์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง ํ์
ํ์ต๋๋ค.

๋ก๊ทธ๋ฅผ ์ฐ์ด๋ณธ ๊ฒฐ๊ณผ ๋ชจ๋์ ๋ค์ด๋ก๋ ํ๋ ๊ณณ์์๋ ๋ฌธ์ ๊ฐ ์์ง๋ง, ๋ชจ๋์ load ํ๋ ๋ถ๋ถ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค๋ ๊ฒ์ ์ฐพ์ ์ ์์์ต๋๋ค. ๋๋ฌด์ง ๊ฐ๋ ์ค์ง ์๋ ๋ฌธ์ ๋ผ์ ์ ๋ง ๋ง๋งํ ์ํฉ์ด์๋๋ฐ์. ๊ธฐ์ ์ ์ผ๋ก(?) ๊ณต์๋ฌธ์์์ ๋ดค๋ ๋ด์ฉ์ ๊ธฐ์ตํด๋ผ ์ ์์์ต๋๋ค.
๋ฒ๋ค๋ฌ๋ก vite๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ชจ๋ umd๊ฐ ์๋ esm ๋ชจ๋์ ์ฃผ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ๊ณต์๋ฌธ์์ ์๋ด๋์ด ์์ต๋๋ค.
์ ๋ด์ฉ์ ๋ฐ๋ผ ffmpeg.wasm์ baseURL ์ฃผ์๋ฅผ esm์ผ๋ก ๋ณ๊ฒฝํด์ ๋ชจ๋ ๋ก๋ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ต๋๋ค.
typescript ์๋ฌ ๋ฐ์
vite๋ก ๋ง์ด๊ทธ๋ ์ด์
ํ ํ๋ก๋์
๋น๋๋ฅผ ์คํ์์ผ๋ณด๋ ์์ ๊ฐ์ด ํ์
์คํฌ๋ฆฝํธ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๊ทธ ์ด์ ๋ react query ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ด๋ถ์์ private ํด๋์ค ๋ฉค๋ฒ ๋ณ์๋ฅผ ์ํด # ํค์๋๋ฅผ ์ฌ์ฉํ๊ณ ์๋๋ฐ ์ด๋ ECMAScript 2015 ์ดํ๋ถํฐ ์ง์๋๋ ๋ฌธ๋ฒ์
๋๋ค.
ํ์ฌ ๊ณฐํฐ๋ทฐ ํ๋ก์ ํธ tsconfig.json์ target ์ค์ ์ es5๋ก ๋์ด์์๊ธฐ ๋๋ฌธ์ ์ด๋ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒ์
๋๋ค.
๋ฐ๋ผ์ target ์ค์ ์ ES2015๋ก ์ฌ๋ ธ์ต๋๋ค.
cloudflare ๋น๋ ์คํจ

๊ณฐํฐ๋ทฐ์์๋ ๊ฐ๋ฐ ํ๊ฒฝ์์ ์ฟ ํค๋ฅผ ์ฌ์ฉํ ํ ํฐ ๋ฐ๊ธ์ ์ํด cookieGenerator๋ผ๋ ์ ํธ์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์ด๋ ๊ฐ๋ฐ ํ๊ฒฝ์์๋ง ์ฌ์ฉ๋๋ ์ฝ๋๋ผ์ env ์ ๋ณด์ ๋ฐ๋ผ ๋์ import๋ฅผ ์ฌ์ฉํด์ ๋ถ๋ฌ์ค๊ณ ์๊ณ , github์๋ ์ฌ๋ฆฌ์ง ์๊ณ ์์ต๋๋ค. ํ์ง๋ง cloudflare์์ ํ๋ก์ ํธ ๋น๋ ์ ํด๋น ํ์ผ์ด ์กด์ฌํ์ง ์์์ typescript ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ ๊น! ์ฌ๊ธฐ์ ์๋ฌธ์ ์ด ์๋๋ฐ์. typescript ์๋ฌ๋ ๋ฒ๋ค๋ฌ์ ์๊ด์ด ์์ํ ๋ฐ ์ webpack์ ์ฌ์ฉํ ๋๋ ์ด๋ฐ ๋ฌธ์ ๊ฐ ์๋ค๊ฐ vite๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ํ ๋ฌธ์ ๊ฐ ๋ฐ๊ฒฌ๋์์๊น์?? ๊ทธ๊ฑด ๋ฐ๋ก webpack์ ์ฌ์ฉํ๋ ๊ธฐ์กด ํ๋ก์ ํธ๋ ๋น๋์์ tsc๋ก ํ์ ์ฒดํฌ๋ฅผ ํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋๋ค....! vite์ ๊ธฐ๋ณธ ์ค์ ์๋ build ๋ช ๋ น์ด์ ์๋์ผ๋ก tsc๊ฐ ํฌํจ๋์ด ์์ด์ ๋ง์ด๊ทธ๋ ์ด์ ์ ์งํํ๋ฉด์ ํ์ ๊ฒ์ฌ๋ฅผ ํ๋ ์ฝ๋๊ฐ ์๋์ผ๋ก ์ถ๊ฐ๋์๊ณ ์ด๋ก ์ธํด ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ๊ฒ ๋ ๊ฒ์ ๋๋ค.
์ผ๋จ์ ์์๋ฐฉํธ ํด๊ฒฐ์ฑ ์ผ๋ก webpack์ ์ฌ์ฉํ๋ ์์ ์ฒ๋ผ ๋น๋์์๋ ํ์ ๊ฒ์ฌ๋ฅผ ํ์ง ์๋๋ก tsc๋ฅผ ์ ๊ฑฐํด๋์ ์ํ์ธ๋ฐ์. ๋์ import์ ํ์ ๋ง์ถ๊ธฐ์ ๊ดํ ๋ด์ฉ์ ํด๊ฒฐ ํ ํ์ ํฌ์คํ ์ผ๋ก ์์ฑํ๊ฒ ์ต๋๋ค.
๋น๋ ์๊ฐ ๋น๊ต
| webpack ํ๋ก๋์ ๋น๋์๊ฐ | vite ํ๋ก๋์ ๋น๋์๊ฐ | webpack ๊ฐ๋ฐ์๋ฒ ๋น๋์๊ฐ | vite ๊ฐ๋ฐ์๋ฒ ๋น๋์๊ฐ | |
|---|---|---|---|---|
| 1 | 3481 ms | 2020 ms | 2656 ms | 116 ms |
| 2 | 3279 ms | 2120 ms | 2601 ms | 115 ms |
| 3 | 3327 ms | 2050 ms | 2625 ms | 118 ms |
| 4 | 3259 ms | 2040 ms | 2649 ms | 117 ms |
| 5 | 3090 ms | 2080 ms | 2520 ms | 116 ms |
| ํ๋ก๋์ ๋น๋์์๋ vite๋ ๊ฐ๋ฐ ์๋ฒ ๋น๋์์ ์ฌ์ฉํ๋ esbuild์ ESM ๋์ rollup์ ์ฌ์ฉํ ๋ฒ๋ค๋ง ๊ณผ์ ์ ์งํํ๊ธฐ ๋๋ฌธ์ ์นํฉ์ ์ฌ์ฉํ ๋์ ์์ฃผ ํฐ ์ฐจ์ด์ ์ ์๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. | ||||
| ํ์ง๋ง esbuild์ ESM์ ์ฌ์ฉํ๋ ๊ฐ๋ฐ ์๋ฒ ๋น๋์์๋ ๊ธฐ์กด ๋๋น ์ฝ 20๋ฐฐ์ ๋ ๋นจ๋ผ์ง ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. |
์ฐธ๊ณ ๋งํฌ
- Vite๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ | Vite
- javascript - Vite๊ฐ tsconfig.json๊ณผ tsconfig.node.json์ด๋ผ๋ ๋ ๊ฐ์ TypeScript ๊ตฌ์ฑ ํ์ผ์ ์์ฑํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? - ์คํ ์ค๋ฒํ๋ก
- Webpack โ Vite: ๋ฒ๋ค๋ฌ ๋ง์ด๊ทธ๋ ์ด์ ์ด์ผ๊ธฐ
- Vite์ ํ๊ฒฝ ๋ณ์์ ๋ชจ๋ | Vite
- Usage | ffmpeg.wasm
- ffmpeg.wasm/apps/react-vite-app/src/App.tsx at main ยท ffmpegwasm/ffmpeg.wasm