Create-React-App ์์ด ๋ฆฌ์กํธ ํ๋ก์ ํธ ํ๊ฒฝ ๊ตฌ์ถํ๊ธฐ
์ง์ ํ๊ฒฝ์ ๊ตฌ์ถํด๋ณด๋ ๊ฒ์ ๋ํด์
CRA๋ ๋ถ๋ช
ํ ๋น ๋ฅธ ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ์์ํ๊ฒ ๋ง๋ค์ด์ฃผ๋ ์ข์ ๋๊ตฌ์์๋ ํ๋ฆผ์๋ค. CRA๋ฅผ ํตํด์ ํ๋ก์ ํธ ์์ฒด๋ฅผ ๋น๋ ํ ์ ์๋ค. CRA๊ฐ ๋์๋ค๋ ์ด์ผ๊ธฐ๋ฅผ ํ๋ ค๊ณ ์ด ๊ธ์ ์ ๋ ๊ฒ์ด ์๋์ ์์์ ๊ฐ์กฐํ๋ค.
๊ทธ๋ผ์๋ ๋ด๊ฐ ์ด ๊ธฐ๋ก์ ๋จ๊ธฐ๋ ์ด์ ๋ ๋๋ฌด ๋งน๋ชฉ์ ์ธ CRA๋ฅผ ๋จ๋ฐํ์ง ์๊ธฐ ์ํจ์ด๋ค. ์นํฉ์ผ๋ก ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ถํด๋ณด๋ฉด์ ์ด๋ค ํ๋ฌ๊ทธ์ธ, ๋ก๋๋ฅผ ์ ์์ ์ ์ฉํด์ผ ํ๋์ง ๋ฐฐ์ฐ๊ธฐ ์ํจ์ด๋ค. ๋ฐ๋ฒจ์ ํตํด์ ์ด๋ป๊ฒ ์ธ์ด์ ๋ฌธ๋ฒ๊ฐ ํธํ์ฑ์ ์ง์ผ์ผ ํ๋์ง๋ฅผ ๊ณต๋ถํ๊ธฐ ์ํจ์ด๋ค.
๊ทธ๋๋ ๋๋ ์ฌ์ ํ CRA๊ฐ ๋๋ฌด ํธํ๊ณ ์ข๋ค. ํ์ํ๋ค๋ฉด CRA๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฐ๋ ๊ฒ๋ ์ข์ ๊ฒ ๊ฐ๋ค.
์์์ ํ์ํ ๋ชจ๋ ์ค์น๋ก๋ถํฐ
๋๋ yarn์ผ๋ก ๋
ธ๋ ๋ชจ๋์ ์ค์นํ๋ ๊ฒ์ ์ข์ํ๋ค. ์กฐ๊ธ ๋ ๋น ๋ฅด๋ค๋ ๋๋๋ ์๊ณ , ํฐ๋ฏธ๋์์ ๋ชจ๋์ ๋ฐ์์๋ ๋์ค๋ ๋ฌธ๊ตฌ๋ ์กฐ๊ธ ๋ ์ธ๋ จ๋ ๊ฒ ๊ฐ์์ ๊ทธ๋ ๋ค. ๊ทธ๋์ ๊ธฐ๋ก์ ๋๋ถ๋ถ์ yarn add
๋ก ๊ตฌ์ฑ๋ ๊ฒ ๊ฐ๋ค.
์ฐ์ , ํ๋ก์ ํธ๋ฅผ ์์ํ ํด๋๋ฅผ ํ๋ ๋ง๋ค๊ณ yarn init -y
๋ก ๋
ธ๋ ํ๋ก์ ํธ์์ ๋๋ฌ๋ธ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฆฌ์กํธ์ ๊ด๋ จ๋ ๋ชจ๋์ ์ค์นํ๋ค. yarn add react react-dom
react-dom์ react์ dom์ ์ง์ ์ ์ผ๋ก ์ฐ๊ฒฐํด์ฃผ๋ ๋ชจ๋์ด๋ค.
Babel
๊ทธ ๋ค์, ์๋ฐ์คํฌ๋ฆฝํธ์ ์๋ก๋ค๋ฅธ ๋ฌธ๋ฒ๊ฐ์ ์ค๋ฅ๋ฅผ ํ๋๋ก ํตํฉํด์ค ๋ฐ๋ฒจ์ ๋ชจ๋๋ค์ ์ค์นํ๋ค. JSX์ ES6 ์ด์์ ๋ฌธ๋ฒ์ ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ๊ฐ ์ดํดํ ์ ์๋๋ก ES5 ๋ฌธ๋ฒ์ผ๋ก ๋ณํํด์ค๋ค. yarn add @babel/core @babel/preset-react @babel/preset-env
๋ฐ๋ฒจ์ ๋ชจ๋์ ์์ '@' ๋งํฌ๊ฐ ๋ถ๋ ํน์ง์ด ์๋ค. ๋ฐ๋ฒจ์ ๋ํ ์์ธํ ์ค๋ช ์ ์ด์ TIL์ ๊ฐ๋ฐํ๊ฒฝ ๊ตฌ์ถ์ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ฒ์ด ์๋ค. ๊ทธ ๋ถ๋ถ์ ํจ๊ป ์ฐธ๊ณ ํ์. ๊ฐ๋ฐํ๊ฒฝ ์ดํดํ๊ธฐ - Babel
- @babel/preset-react : ๋ฆฌ์กํธ์ JSX ๋ฌธ๋ฒ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํํด์ค๋ค.
- @babel/preset-env : ES6 ์ด์์ ์๋ฐ์คํฌ๋ฆฝํธ ๋ฌธ๋ฒ์ ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ ธ์์๋ ํธํ ๊ฐ๋ฅํ๋๋ก ES5๋ก ๋ณํํด์ฃผ๋ ํ๋ฆฌ์ ์ด๋ค.
Webpack and Loader
ํ๋ก์ ํธ ํ๊ฒฝ ๊ตฌ์ถ์ ํต์ฌ์ธ ์นํฉ๊ณผ ๊ด๋ จ ๋ชจ๋์ ์ค์นํ๋ค.
yarn add -D webpack webpack-cli webpack-dev-server babel-loader css-loader style-loader
webpack-dev-server
: ์ด๋ฆ์์๋ ์ ์ ์๋ฏ์ด ๊ฐ๋ฐ ๋ชจ๋์ ํ์ํ ์๋ฒ๋ฅผ ๊ตฌ๋ํด์ค๋ค. ์ปดํจํฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋น๋ ค ์นํฉ์ ๊ตฌ๋ํ๊ณ ์0์ ์๋ฒ๋ฅผ ๋์ฐ๋ ์ญํ ์ ํ๋ค.css-loader, style-loader
: css ๋ฌธ๋ฒ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ณํํด์ฃผ๋ ์ญํ ์ ํ๋ค. / css-loader๊ฐ ๋ณํํ ํ์ผ์ index.html์<style>
ํ๊ทธ์ ๋ฃ๋ ์ญํ ์ ํ๋ค.
๊ทธ ๋ค์, ๋ฒ๋ค๋ง ํ์ผ์ ์ ์ฉํ ํ๋ฌ๊ทธ์ธ์ ์ค์นํ๋ค.
yarn add -D html-webpack-plugin clean-webpack-plugin
html-webpack-plugin
: htmlํ์ผ์ ๋ฒ๋ค๋ง๋ ๋ฆฌ์กํธ ์ฝ๋๋ฅผ ์ฝ์ ํด์ค๋ค. ๊ทธ๋ฆฌ๊ณ dist ํด๋์ ๋ฒ๋ค๋ง๋ ํ์ผ์ ์ฎ๊ฒจ์ฃผ๋ ์ญํ ์ ํ๋ค.clean-webpack-plugin
: ๋ฒ๋ค๋ง์ด ์๋ฃ๋ ๋๋ง๋ค ์ด์ ์ ๋ฒ๋ค๋ง ๊ฒฐ๊ณผ๋ฅผ ์ ๊ฑฐํด์ฃผ๋ ์ญํ ์ ํ๋ค.
์ด์ ๋ฐ๋ฒจ, ์นํฉ ์ค์ ํ์ผ์ ๋ง๋ค๋ฉด์ ํ๋ก์ ํธ ํ๊ฒฝ์ ์์ฑํด๋ณด์.
babel.config.js
๋ฐ๋ฒจ ์ค์ ํ์ผ์๋ ํ๋ฆฌ์
์ ์ ์ ์ฉํด์ฃผ๋ ๊ฒ์ด ์ค์ํ๋ค. ํ๋ฆฌ์
์ ๋ฐ๋ฒจ์ ์ญํ ๋ค์ ๋ชจ์๋ ๋๊ตฌ ์์๋ผ๊ณ ์๊ฐํ๋ฉด ํธํ๋ค. .babelrc
์ด๋ฆ์ผ๋ก ํ์ผ ์ด๋ฆ์ ์ง์ ์๋ ์๋ค. ์ด๋ ๊ฒ ์ฌ์ฉํ ํ๋ฆฌ์
์ presets
ํญ๋ชฉ์ ๋ฐฐ์ด๋ก ๋ฃ์ด์ฃผ๋ฉด๋๋ค.
// babel.config.js
module.exports = {
presets: ['@babel/preset-env', '@babel/preset-react']
};
webpack.config.js
๊ฐ์ฅ ์ค์ํ ์ค์ ์ ์นํฉ ์ค์ ์ด๋ค. ์ค์ง์ ์ผ๋ก ์นํฉ์ผ๋ก ์ด๋ป๊ฒ ๋ฒ๋ค๋ง์ ํ๋์ง์ ๋ฐ๋ผ์ ํ๋ก์ ํธ์ ๊ฒฐ๊ณผ๊ฐ ์์ ํ ๋ฌ๋ผ์ง ์ ์๋ค. webpack.config.js
ํ์ผ์ ๊ตฌ์ถํ๋ฉด์ ๊ผผ๊ผผํ๊ฒ ์์๋ณด์.
// webpack.config.js
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const dotenv = require('dotenv').config();
์ค์ ์์ ์ฌ์ฉํ๋ ๊ฐ๋ฐ ๋ชจ๋/ํ๋ก๋์ ๋ชจ๋๋ฅผ ๊ตฌ๋ถํ๊ณ ๊ฐ๋ฐ ์๋ฒ์ ํฌํธ ๋ณํธ๋ฅผ ํ๊ฒฝ๋ณ์๋ก ๊ด๋ฆฌํ๊ธฐ ์ํด์ dotenv๋ฅผ ์ค์นํด์ ์ฌ์ฉํ๋ค.
module.exports = {
mode: process.env.mode,
entry: './src/index.js',
output: {
path: __dirname + '/dist',
filename: 'bundle.[hash].js',
publicPath: '/'
},
resolve: {
// path.resove ํํ๋ก ์ฌ์ฉํ ์๋ ์๋ค.
// ๊ทธ๋ฌ๋ฉด node์ ๊ธฐ๋ณธ ๋ชจ๋ 'path'๋ฅผ ๋ถ๋ฌ์์ผ ํ๋ค.
extensions: ['.js', '.jsx']
}
};
๋ฒ๋ค๋ง์ด ์์๋ ๊ณณ์ ๋ฆฌ์กํธ ํ๋ก์ ํธ์์ ๋ณดํต ๋ฆฌ์กํธ ๋์ ๋๋๋ง์ ๊ฑฐ๋ index.js
๋ก ์ ํ๋ค. ์ํธ๋ฆฌ ํฌ์ธํธ๋ ๊ฐ๋ฐ์๊ฐ ์์์ ์ ํด์ฃผ๋ฉด ๋๋ค. ๋ฒ๋ค๋ง ๊ฒฐ๊ณผ๋ ๋ณดํต dist ํด๋์ ํด์ฌ๊ฐ ๋์ฑ๋ก ์ ์ฅ๋๋ค. ๋ฒ๋ค๋ง์ ํ ํ์ผ์ '.js, .jsx'์ ํ์ฅ์๋ฅผ ๊ฐ์ง ํ์ผ์ด๋ค. ๋๋ ๋ณดํต ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ฆฌ์กํธ ํ๋ก์ ํธ๋ฅผ ํ ๊ฒฝ์ฐ ์ปดํฌ๋ํธ ํ์ผ๋ช
์ '.jsx' ํ์ฅ์๋ก ์ง๋๋ค.
module.exports = {
...,
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: '/node_modules/',
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [{ loader: 'style-loader' }, { loader: 'css-loader' }]
}
]
},
}
๋ก๋๋ rules ํญ๋ชฉ์์ ์ง์ ํด์ค ์ ์๋ค. ์ค์ ์ ์ผ๋ก ์ ๊ฒฝ์จ์ผ ํ๋ ๊ฒ์ ๋ก๋์ ์์๋ค. ์นํฉ์ ๋ฑ๋กํ ๋ก๋์ ๋ฐฐ์ด์์ ๋ค์ ์์๋ถํฐ ๋ฒ๋ค๋ง์ ๋ฐ์ํ๋ค. css๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ณํํ ๋ค์ style ํ๊ทธ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์ ์์๋ฅผ ๊ฐ์ง๋ค. ๋ํ node_modules ํด๋์ ๋ชจ๋ ๋ชจ๋๋ค์ ๋ค ๋ฒ๋ค๋ง ํ ํ์ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฑธ ์ ์ธํด์ฃผ๋ ๊ฒ๋ ์ค์ํ๋ค.
module.exports = {
...,
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: 'public/index.html'
}),
new webpack.DefinePlugin({
mode: process.env.mode,
port: process.env.port
})
],
devServer: {
host: 'localhost',
port: process.env.port,
open: true,
historyApiFallback: true,
hot: true
}
}
ํ๋ฌ๊ทธ์ธ์ ๊ฐ ์์ฑ์ ํจ์๋ก ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๋ฐฉ์์ผ๋ก ์ ์ฉํ๋ค. DefinePlugin
์ ๊ฒฝ์ฐ ์นํฉ์ ๊ธฐ๋ณธ ํ๋ฌ๊ทธ์ธ์ด๋ผ์ webpack์ผ๋ก ๋ถํฐ ๊ฐ์ง๊ณ ์๋ค. .env
ํ์ผ์ ๋ฑ๋กํ ๊ฐ๋ฐ ๋ชจ๋์ ํฌํธ ๋๋ฒ๋ฅผ ๋ฑ๋กํด์ ์ฌ์ฉํ ์ ์๊ฒ ํด์ค๋ค.
devServer
๋ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์ด์ด์ฃผ๋ ์ฉ๋๋ค. 'hot' ํค์๋๋ฅผ true ๊ฐ์ผ๋ก ์ค์ ํด์ ๋ณํ๊ฐ ๋ฐ์ํ๋ฉด ๋ฐ๋ก ๋ฒ๋ค๋ง์ด ๋ฐ๋๋๊ณ ์๋ฒ์ ๋ฐ์๋ ์ ์๋๋ก ์ค์ ํด์ฃผ๋ฉด ์ฐ๋ฆฌ๊ฐ react ํ๋ก์ ํธ์์ ๋ ๋ดค๋ 'yarn start'๋ฅผ ๋ง๋ค์ด์ค๋ค. ๋ฌผ๋ก ์คํฌ๋ฆฝํธ์ ๋ฑ๋ก์ ํด์ผํ๋ค.
package.json ํ์ผ์ ์คํฌ๋ฆฝํธ ๋ฑ๋กํ๊ณ ๋ฆฌ์กํธ ๊ฐ๋ฐ ์์ํ๊ธฐ
"scripts": {
"start": "webpack serve --progress --mode development",
"build": "webpack"
}
"start" ๋ช
๋ น์ด์ 'webpack-dev-server'๋ฅผ ๋ฑ๋กํด์ ๋ฆฌ์กํธ ์คํฌ๋ฆฝํธ๊ฐ ๋์ํ ์ ์๋๋ก ์ค์ ํ๋ค. 'hot' ํค์๋๊ฐ ๋ฑ๋ก๋์ด ์๊ธฐ๋๋ฌธ์ ํ๋ก์ ํธ๋ ๋ฆฌ์กํธ์ ์ฌ์ํ ๋ณํ๋ฅผ ๋ฐ์ํ ์ ์๋ค. "build" ๋ช
๋ น์ด๋ฅผ ๋์ํ๋ฉด dist ํด๋์ ๋ฒ๋ค๋ง๋ ํ์ผ๋ค์ด ์์ฑ๋ ๊ฒ์ด๋ค.
์ด์ ์ฐ๋ฆฌ์๊ฒ ๋จ์ ๊ฒ์ public/index.html
์ ์์ฑํ๊ณ src/index.js
์ ๊ฐ๋ฒผ์ด ๋ฆฌ์กํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด๋ค. ๋ฌผ๋ก yarn start
๋ช
๋ น์ด๋ก ์นํฉ์ ๋๋ฆฌ๊ณ 3000๋ฒ ํฌํธ(.env์ ์ค์ ํด์ค)์์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๋ ๊ฒ์ ๋ค์ด๋ค.
<!-- public/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=divice-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>react-twittler</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
// index.js
import React from 'react';
import ReactDom from 'react-dom';
const App = () => {
return <div>hello hankyeol</div>;
};
ReactDom.render(<App />, document.getElementById('root'));
๋ถ๋๋ฝ์ง๋ง.. ํ์ฌ์์ ํด๋น ๋ด์ฉ์ผ๋ก ๊ธฐ์ ๋ฐํ ์์์ ์ฐ์๋ค.