최근 아시는 분들과 프론트 개발에 대해 이야기를 나누다가 이런 이야기를 하였습니다.
너 CRA 없이 React 프로젝트 셋팅은 할 수 있냐?
곰곰이 생각해보니 React를 배울 때 부터 Create-React-App 을 사용한 개발만 해왔기에 CRA 없이 한번도 React 프로젝트 셋팅을 해보지 않은 사실을 알고 부끄러움을 느꼈습니다.
대략적으로 Webpack + Babel + ReactJS + Live-Server를 설정하고 나머진 필요할 때 설치하면 되지 않을까? 란 생각을 하였지만 실제로 설정을 해보니 쉽지 않았습니다.
그래서 복습도 하고 다시 한번 정리도 할 겸 이 시리즈를 시작하게 되었습니다 :)
이 글은 제가 이해한 지식을 바탕으로 서술 되었기 때문에 글에 잘못된 내용이 있다면 댓글로 가르침을 주시면 정말 정말 감사하겠습니다.
이 포스팅에서 사용한 예제는 여기서도 확인 하실 수 있습니다.
이 문제에 대한 대답을 찾기 위해 React 공식 문서를 찾아보았습니다.
교과서만 보면 수능 만점을 맞을 수 있습니다.
그리고 React 공식 문서를 제대로 안 읽은 것을 꾸짖는 것 처럼 1번째 Installation 섹션에 관련 내용이 나와있었습니다.. 쥐구멍은 어디인가?
Installation 섹션을 보면 리액트 개발을 위한 여러가지 방법들을 설명하고 있습니다.
React 공식 문서는 최고의 사용자 경험과 개발자 경험을 위해 통합 개발 도구를 사용하는 것을 추천하고 있습니다.
추천되는 개발도구들은 다음과 같습니다.
또한 React docs에 따르면 위 도구들은 다음과 같은 특성들을 도와준다고 합니다.
공식 문서는 또한 사용자가 스스로 JavaScript 도구들을 사용하여 처음부터 구성을 할때 다음과 같은 도구들을 사용하라고 되어있습니다.
또한 사용자가 직접 만든 도구를 설정할 때 production을 위한 다음과 같은 설정을 하라고 되어 있습니다.
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
}),
new webpack.optimize.UglifyJsPlugin()
문서의 내용을 바탕으로 스스로 React 개발 환경을 설정하기 위해서는 아래와 같은 우선 순위가 있다고 생각하였습니다.
필수사항
개발 편의성을 위한 선택 사항
이제 우선 순위가 정리 되었으니 파일을 만들고 차례대로 설정을 해보겠습니다.
우선 프로젝트 설정을 위한 파일을 하나 생성하고 기본 파일 구조를 위해 src
폴더와 public
폴더를 만들도록 하겠습니다.
$ mkdir react-a-to-z && cd react-a-to-z
$ mkdir -p src public
package manager는 yarn 과 npm이 있습니다만 저는 npm 사용이 좀 더 익숙하기에 npm 을 사용하도록 하겠습니다. 둘 중 어떤 것을 사용하셔도 무방합니다.
$ npm init -y
Webpack은 Front-end 개발을 할 때 필요한 많은 설정 들을 지원해주는 강력한 도구 입니다. React app은 Component라는 모듈 단위로 개발되는데 개발되는 component들을 묶어 주는 역할을 합니다.
$ npm install --save-dev webpack webpack-cli
설치가 완료 되면 프로젝트 파일에 있는 package.json
파일에 다음과 같은 명령어를 추가해 줍니다.
...
"scripts": {
"build": "webpack --mode production",
},
...
Webpack을 제대로 사용하기 위해서는 webpack.config.js
파일을 생성해주고 추가적인 설정을 해줘야 합니다.
const path = require("path");
module.exports = {
mode: "development",
entry: {
main: './src/index.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'build')
},
resolve: { extensions: ["*", ".js", ".jsx"] },
};
위의 설정 들을 간략히 설명하자면 다음과 같습니다.
production
or development
이 설정들은 Webpack의 동작을 정의하는 설정들입니다. 다음으로 Webpack이 동작할 때 Html과 CSS파일을 인식하기 위한 추가적인 설정을 해보겠습니다.
html 설정
$ npm install --save-dev html-webpack-plugin clean-webpack-plugin
CSS 설정
$ npm install --save-dev mini-css-extract-plugin css-loader sass-loader file-loader
위 라이브러리들이 다 설치가 되었으면 webpack.config.js
파일에 설정을 추가해 보겠습니다.
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const webpack = require('webpack');
module.exports = {
mode: "development",
entry: {
main: './src/index.js'
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: true,
reloadAll: true
}
},
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|jpg|svg|gif)/,
use: [
'file-loader'
]
}
]
},
resolve: {
extensions: [ '*', '.js', '.jsx' ]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'webpack-react-start-kit',
template: './public/index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
}),
]
}
이어서 처음 생성한 public
폴더에 index.html
폴더를 만들도록 하겠습니다.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>React A to Z</title>
</head>
<body>
<div id="root"></div>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
</body>
</html>
지금 설정한 Webpack 설정들은 다음과 같습니다.
HTML
html-webpack-plugin
: Webpack이 실행 될 때 public
파일에 설정한 html 파일을 기준으로 결과물을 만들어줍니다.clean-webpack-plugin
: Webpack이 실행될 때 이전에 나온 결과물을 제거합니다.(최신 결과물 만을 유지하기 위해)CSS
Sass-loader
, css-loader
: Webpack을 실행할 때 CSS와 Sass 파일을 적용해 주는 패키지 입니다.mini-css-extract-plugin
: css 결과물을 여러 개의 chunk 파일로 분리 시켜주는 라이브러리 입니다.React component 들은 JavaScript ES6+ 문법과 JSX 문법으로 작성됩니다. 이 코드를 그대로 쓰는 경우 지원하지 않는 브라우저에서는 코드가 동작하지 않으므로 Babel을 사용하여 Transpiling
을 해줘야 합니다.
$ npm install --save-dev @babel/core babel-loader @babel/preset-env @babel/preset-react
설치된 라이브러리들에 대한 설명을 해드리자면 아래와 같습니다.
설치가 다 되셨으면 Babel 적용을 위한 설정 파일을 만들도록 하겠습니다.
.babelrc
파일을 만들고 다음과 같이 입력 해주시면 됩니다.
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
React 프로젝트를 위한 필수 항목을 다 설치하였습니다. 마지막으로 Babel과 Webpack을 연동해 보겠습니다.
우선 Webpack 설정 파일 webpack.config.js
파일을 만들고 아래와 같은 설정을 입력해주세요.
module.exports = {
...,
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
};
이제 필요한 도구를 모두 설정하였습니다.
이제 React 라이브러리를 설치하고 컴포넌트를 만들어 보도록 하겠습니다.
$ npm install react react-dom
src/Index.js
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(<div>Hello React</div>, document.getElementById('root'));
파일을 저장하고 나서 npm run build
를 실행시켜 보시면 build 파일이 생성되어 있고 내부에
index.html
과 main.bundle.js
파일이 생성되어있습니다. html 파일을 열어보시면 결과는 다음과 같습니다.
이로써 필수 요구사항을 모두 만족한 React 프로젝트가 생성되었습니다.
다음으로 선택 사항 중 실시간 개발 서버를 적용해 보도록 하겠습니다.
$ npm install webpack-dev-server
설치가 완료되면 webpack.config.js
파일에 다음 설정을 추가해 주세요.
...
module.exports = {
...,
devtool: 'inline-source-map',
devServer: {
contentBase: './build',
noInfo: true,
open: true,
port: 9000,
after: function(app, server) {
app.listen(3000, function () {
console.log("Webpack dev server is listening on port 9000");
})
}
},
plugins: [
...,
new webpack.HotModuleReplacementPlugin()
]
...
}
저희가 설치한 webpack-dev-server
라이브러리는 express 기반의 개발 서버로 코딩의 변경 사항을 실시간으로 적용해서 보여주는 역할을 합니다.
package.json
에 다음과 같은 명령어를 추가하고 바로 실행해 보도록 하겠습니다.
"scripts": {
...,
"start": "webpack-dev-server"
}
npm run start
명령어를 커맨드 창에서 실행하면 브라우저가 켜지면서 실행 결과를 보여줍니다.
이제 index.js
파일을 변경하시면 변경사항이 바로 저장되는 것을 보실 수 있습니다.
이제 React 프로젝트 셋팅을 완료 하였습니다.
다음 시리즈는 이 완성된 프로젝트를 사용하여 TDD를 이용한 컴포넌트 개발을 해보도록 하겠습니다.
긴 글 읽어주셔서 정말 감사합니다.
잘 정리해주셔서 두고두고 참고 하겠습니다.
감사합니다.