๐Ÿ“– TIL - "Vite & CRA์•ผ ๊ณ ๋งˆ์›Œ..." React ํ™˜๊ฒฝ ๊ตฌ์ถ•๊ธฐ

์Š˜ยท2025๋…„ 1์›” 27์ผ

๐Ÿ“– TIL

๋ชฉ๋ก ๋ณด๊ธฐ
38/89

๐Ÿ“Œ ๋ฌธ์ œ ์„ค๋ช…

React ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊ตฌ์ถ•๊ธฐ.
CRA๋‚˜ Vite์˜ ๋„์›€ ์—†์ด ์ˆœ์ˆ˜ํ•˜๊ฒŒ React ํ™˜๊ฒฝ์„ ๊ตฌ์ถ•ํ•ด๋ณด๋ฉด์„œ ๊ฒช์€ ์‹œํ–‰์ฐฉ์˜ค์™€ ํ•ด๊ฒฐ ๊ณผ์ •์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

๐Ÿค” ๊ฐœ๋ฐœ ๊ณผ์ •๊ณผ ๋ฌธ์ œ ํ•ด๊ฒฐ

1. ๊ธฐ๋ณธ ํ™˜๊ฒฝ ๊ตฌ์„ฑ

  • no-cra ํด๋” ์ƒ์„ฑ
  • index.html์— root div ์ถ”๊ฐ€
  • React์™€ ReactDOM CDN ์ถ”๊ฐ€

CDN์œผ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ์ด์œ ?
1. ๋น ๋ฅธ ์‹œ์ž‘ - npm install ์—†์ด React ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ๋น ๋ฅด๊ฒŒ ์„ธํŒ…
2. UMD ๋ฒ„์ „ - ๋ธŒ๋ผ์šฐ์ € ํ™˜๊ฒฝ์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ˜•์‹์œผ๋กœ ๋นŒ๋“œ๋จ
3. ์›นํŒฉ์ด๋‚˜ ๋ฐ”๋ฒจ ๊ฐ™์€ ๋นŒ๋“œ ๋„๊ตฌ ์—†์ด๋„ React ์‚ฌ์šฉ ๊ฐ€๋Šฅ

2. ์ฒซ ๋ฒˆ์งธ ๋‚œ๊ด€: JSX ๋ฌธ๋ฒ• ์—๋Ÿฌ

// SyntaxError: Unexpected token '<'
// JSX๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฌธ๋ฒ•์ด ์•„๋‹Œ, ํ™•์žฅ ๋ฌธ๋ฒ•์ด์—ˆ๋‹ค...

3. ํ•ด๊ฒฐ ์‹œ๋„

๋ฐฉ๋ฒ• 1: ์ˆœ์ˆ˜ React ๊ตฌ๋ฌธ์œผ๋กœ ์ž‘์„ฑ

const App = () => React.createElement('h1', null, 'Hello, React without CRA!');
ReactDOM.createRoot(document.getElementById('root')).render(React.createElement(App));

๋ฐฉ๋ฒ• 2: Babel ๋„์ž…

<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">

"transformScriptTags.ts:253 You are using the in-browser Babel transformer..."
๋ธŒ๋ผ์šฐ์ €์—์„œ ์‹ค์‹œ๊ฐ„ ๋ณ€ํ™˜์€ ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ๊ฒฝ๊ณ ๊ฐ€ ๋œฌ๋‹ค!

4. Babel ์ •์‹ ์„ค์ •

npm init -y
npm install --save-dev @babel/core @babel/cli @babel/preset-react
// .babelrc
{
  "presets": ["@babel/preset-react"]
}

5. ๋ฒˆ๋“ค๋Ÿฌ ๋„์ž… ๊ณ„๊ธฐ

"์ž ๊น... ํŒŒ์ผ์ด 100๊ฐœ ์ด์ƒ์ด๋ฉด? ์‹ค์ œ ๋ธŒ๋ผ์šฐ์ €๋Š” ํ•œ ๋ฒˆ์— 6๊ฐœ์”ฉ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๊ฐ€์ ธ์˜ค๋Š”๋ฐ,
์‚ฌ์šฉ์ž๊ฐ€ ๊ตฌ๋‹ฅ๋‹ค๋ฆฌ ๋„คํŠธ์›Œํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด... ์–ด๋–กํ•˜์ง€?"

npm install --save-dev webpack webpack-cli babel-loader

6. Webpack ์„ค์ •์˜ ์ง„ํ™”

๊ธฐ๋ณธ ์„ค์ •

module.exports = {
  entry: "./src/app.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  // ...
}

์บ์‹œ ๋ฌธ์ œ ํ•ด๊ฒฐ

// ํŒŒ์ผ๋ช…์— ํ•ด์‹œ๊ฐ’ ์ถ”๊ฐ€
filename: "bundle.[contenthash].js"

7. ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ๊ธฐ๋Šฅ ํ™•์žฅ

HTML ์ž๋™ ์ƒ์„ฑ

npm install --save-dev html-webpack-plugin

์ด์ „ ๋ฒˆ๋“ค ํŒŒ์ผ ์ •๋ฆฌ

npm install --save-dev clean-webpack-plugin

HMR ์„ค์ •

devServer: {
    static: {
      directory: path.join(__dirname, "dist"),
    },
    port: 9000,
    open: true,
    hot: true,
}

8. ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ด€๋ฆฌ

# .env.development
APP_API_URL=https://dev-api.example.com

# .env.production
APP_API_URL=https://api.example.com
npm install --save-dev dotenv-webpack cross-env

โœจ ์ƒˆ๋กญ๊ฒŒ ๋ฐฐ์šด ์ 

  1. ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ์™€ ๋ฒˆ๋“ค๋Ÿฌ์˜ ์ฐจ์ด

    • Babel: JSX โ†’ ์ˆœ์ˆ˜ JavaScript
    • Webpack: ์—ฌ๋Ÿฌ ํŒŒ์ผ์„ ํ•˜๋‚˜๋กœ ๋ฌถ๊ธฐ
  2. ๋ธŒ๋ผ์šฐ์ € ์บ์‹œ ์ „๋žต

    • contenthash๋กœ ํŒŒ์ผ๋ช… ๋™์  ์ƒ์„ฑ
    • ์บ์‹œ ๋ฌด๋ ฅํ™” ๋ฐฉ๋ฒ•
  3. ํ™˜๊ฒฝ๋ณ„ ์„ค์ • ๊ด€๋ฆฌ

    • development vs production
    • cross-env๋กœ ํฌ๋กœ์Šค ํ”Œ๋žซํผ ํ˜ธํ™˜์„ฑ
  4. ์›นํŒฉ ํ”Œ๋Ÿฌ๊ทธ์ธ ์‹œ์Šคํ…œ

    • ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋™๊ธฐ์  ์‹คํ–‰
    • ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•œ ์ด์œ 

๐Ÿš€ ์ด๋Ÿฐ ์ ์ด ํšจ์œจ์ ์ด์—์š”

  • ๋ชจ๋“  ๋นŒ๋“œ ๊ณผ์ • ์ž๋™ํ™”
  • ํ™˜๊ฒฝ๋ณ„ ์ตœ์ ํ™” ๊ฐ€๋Šฅ
  • HMR๋กœ ๊ฐœ๋ฐœ ์ƒ์‚ฐ์„ฑ ํ–ฅ์ƒ
  • ๋ถˆํ•„์š”ํ•œ ํŒŒ์ผ ์ž๋™ ์ •๋ฆฌ

โญ๏ธ ๋งˆ๋ฌด๋ฆฌ ์ƒ๊ฐ

์ง์ ‘ ๋‹ค๋ฃจ์–ด๋ณธ React ํ™˜๊ฒฝ ๊ตฌ์ถ•๊ธฐ...์ •๋ฆฌํ•˜๊ณ  ์šฉ์–ด ์ฐพ๊ณ , ๊ฒ€์ƒ‰ํ•˜๋‹ค๋ณด๋‹ˆ ์ƒ๊ฐ๋ณด๋‹ค ์˜ค๋ž˜๊ฑธ๋ ธ์ง€๋งŒ
๋•๋ถ„์— CRA๋ฐ Vite๊ฐ€ ํ•ด์ฃผ๋Š” ์ผ๋“ค์„ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•˜๊ฒŒ ๋๋‹ค!
์ด์ œ๋Š” 'npx create-react-app'๋‚˜ 'yarn create vite xxxx โ€”template react'์„ ์ž…๋ ฅํ•  ๋•Œ๋งˆ๋‹ค ๊ฐ์‚ฌํ•œ ๋งˆ์Œ์ด ๋“ค ๊ฒƒ ๊ฐ™๋‹ค... ๐Ÿ˜…
๋˜ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋งŒ๋“œ์‹ ๋ถ„๋“ค๊ป˜๋„ ์‹ฌ์‹ฌํ•œ ๊ฐ์‚ฌ์˜ ๋ง์”€์„....!
๋‚˜์ค‘์—” ์–ด๋–ค ํ”Œ๋Ÿฌ๊ทธ์ธ๋“ค์ด ์Ÿ์•„์ ธ๋‚˜์˜ฌ์ง€ ๊ธฐ๋Œ€๋œ๋‹ค!!

profile
์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ์„ฑ์žฅ๊ธฐ ๊ธฐ๋ก๊ธฐ๋ก

0๊ฐœ์˜ ๋Œ“๊ธ€