리액트 프로젝트 초기셋팅시 eate React App
를 사용하면 리액트에 필수적인 바벨(Babel)과 웹팩(Webpack)을 복잡한 환경 설정 없이 사용할 수 있으며 바로 build 하여 실행할 수 있기 때문에 편리하다. 하지만 내가 셋팅한게 아니다보니 어떤식으로 작동되는지 감이 잡히지 않아 직접 셋팅을 해보기로 했다.
리액트는 ES5/ES6 + jsx 로 작성하는데,
브러우저마다 호환성이 다르기 때문에 읽을 수 있는 코드로 변경해 주어야 한다.
이때! 바벨
이 ES6를 ES5로, jsx를 js로 트랜스 파일링 해주는 역할
을 한다.
리액트는 첫 로딩시, 최종으로 번들된 js 파일이 연결된 html 파일을 로드한다.
웹팩
은 여러 개의 컴포넌트로 분리되어 있는 js 파일을 하나의 번들 파일로 만들어주는 역할
을 한다.
npm init
명령을 실행한다npm init
npm install react react-dom
package.json
의 dependencies
에 react, react-dom
이 생긴것을 확인한다index.html
파일을 작성한다.<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
src
디렉토리를 만들고, src 디렉토리 내에서 components
디렉토리를 만든다. components 디렉토리에서 App.jsx
파일을 작성한다.import React from "react";
const App = () => {
return <div>hello world!</div>;
};
export default App;
index.jsx
파일을 작성한다.import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render(<App />, document.querySelector('#root'));
@babel/core
: 바벨을 사용하기 위한 필수 모듈@babel/preset-env
: 바벨에서 스크립트 코드
를 트랜스 파일링
하기 위한 플러그인들을 모아둔 모듈@babel/preset-react
: 바벨에서 리액트 코드
를 트랜스 파일링
하기 위한 플러그인들을 모아둔 모듈babel-loader
: 웹팩을 돌릴 시에 바벨을 적용하기 위한 모듈npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader
module.exports = function(api) {
api.cache(true);
const presets = ["@babel/preset-env", "@babel/preset-react"];
const plugins = [];
return {
presets,
plugins
};
};
webpack
: 웹팩 모듈webpack-cli
: 웹팩 명령어를 커맨드 라인에서 실행할 때 필요한 모듈html-webpack-plugin
: 웹팩 실행이 완료된 번들 파일을 붙인 html 파일을 만들어 주는 모듈npm i -D webpack webpack-cli html-webpack-plugin
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index",
resolve: {
extensions: [".js", ".jsx"]
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: "babel-loader",
exclude: /node_modules/
}
]
},
output: {
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
plugins: [
new HtmlWebpackPlugin({
// index.html에 output에서 만들어진 bundle.js를 적용하여, dist에 새로운 html 파일 생성
template: `./public/index.html`
})
]
};
package.json 파일의 “script”에 아래와 같이 설정을 추가한다.
"scripts": {
"start": "webpack"
},
웹팩을 실행하기 위해 npx webpack
명령을 해야 하지만..! 위와같이 설정해주면 npm start
로 웹팩을 실행할 수 있다.
npm start
명령을 실행하여 dist 디렉토리
에 생성된 bundle.js
파일과 index.html
파일을 확인한다. index.html 파일을 열어 결과를 확인한다.
dist 디렉토리에 아래와 같은 index.html
이 생성되었다...!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
코드를 수정한 다음 계속해서 npm start
명령을 실행하여 번들을 다시 해주고 확인하는 일은 매우 번거로운 일이다. webpack-dev-server
모듈을 사용하면 번거로움을 줄일 수 있다.
webpack-dev-server
는 변경 사항이 있을 때 마다 자동으로 다시 webpack을 실행해주고 결과 화면을 업데이트를 해주는 모듈이다.
npm i -D webpack-dev-server
명령을 실행하여 모듈 설치한다.
package.json
파일의 script
를 아래와 같이 수정한다.
"scripts": {
"start": "webpack-dev-server --open"
}
webpack.config.js
파일에 아래에 devServer
설정을 추가한다.
devServer: {
contentBase: path.join(__dirname, "dist"), // 이 경로에 있는 파일이 변경될 때 번들을 다시 컴파일
compress: true,
port: 8080 // 각자의 portNumber 작성
},
npm start
하면 브라우저가 열리고, App.jsx
에 있는 hello world 텍스트를 변경하였을 때 실시간으로 변경이 반영 되는 것을 확인할 수 있다.
[ERROR] [ App.jsx
와 index.jsx
의 확장자를 js
로 변경하게되면 아래와 같은 에러가 뜨게되는데
이경우 npm start
를 다시 재실행해주면 문제가 해결된다.