Create-React-App
React를 처음 배우면서, 항상 CRA(Create-React-App)를 사용하여 리액트 앱을 생성하였다.
React로 개발을 시작하기 위해서는 웹팩(Webpack), 바벨(Babel), 번들러(Bundler), 로더(Loader), 플러그인(Plugin), 린트(Eslint), dependencies와 devDependencies 등등 하나하나 배우고 설정해야 할 기술들이 굉장히 많은데 리액트 초심자로서 이것들을 일일히 다 숙지하고 프로젝트를 시작하기에는 실질적으로 힘들기 때문이었다.
Create-React-App의 장점은 CRA로 앱을 생성하면 보편적으로 개발자들이 많이 사용하는 라이브러리 등이 대부분 셋팅 되어있기 때문에, 이후 추가적으로 필요한 라이브러리 등만 설치해주면 복잡한 설정들 없이 초기 설정이 간편하고 빠르게 완료된다는 것이다.
단점으로는 웹팩(Webpack), 바벨(Babel), 린트(Eslint) 등 세부 설정이 package.json 안에 숨겨져 있어 구성요소들을 세부 설정이나 수정하기 위해서는 *eject하여 숨겨진 설정들을 밖으로 꺼내야 한다는 것이 익숙하지 않으면 다소 힘들고 어렵다는 점이다.
creact-react-app eject
creact-react-app eject
eject 실행시 한 번 실행하면 되돌릴 수 없어 앞으로의 설정들을 스스로 해결해나가야 하기 때문에 주의를 기울이며 사용해야 한다. (프로젝트 초반에는 옮겨가면 되니깐 괜찮지만 이후에는 엄청난 양의 dependencies가 가득찬 패키지 파일이 두배로 늘어나는걸 경험하고 싶지 않다면 주의) > 이런 문제를 해결하기 위해 react-app-rewired라는 모듈이 있는데, eject하지 않고 설정파일들을 덮어씌워 변경하고싶은 부분만 rewired를 통해 변경할 수도 있다고 한다.
어쨌든, 실제로 회사에서 업무를 수행하거나 규모가 큰 프로젝트를 진행하다 보면 웹팩이나 바벨 린트 등등 세부설정을 직접 손봐야 하는 경우가 많기 때문에 CRA보단 직접 웹팩과 바벨을 설정하여 자체적으로 프로젝트를 생성하고 관리해야 한다고 한다. 아직 구성요소들이 익숙하지는 않지만 CRA없이 리액트 개발환경을 셋팅하는 방법을 익혀보려고 한다.
Create-React-App 없이 개발환경 셋팅하기
*terminal : git bash
1. 폴더 생성 및 초기화
test 프로젝트 파일을 생성하고 pakage.json 파일을 초기화한다.
mkdir test // test 파일 생성
cd test // test파일로 이동
npm init -y// pakage.json 파일 초기화
*npm : node.js를 위한 패키지 매니저 : node.js에서 사용하는 모듈들을 패키지로 만들어 관리 배포 한다. (CRA에서는 yarn을 주로 사용했다.)
git도 연동하자.
git init // git초기화, git 연동 가능
프로젝트 폴더에 pakage.json과 .git이 생성되었는지 확인한다.
2. 리액트 핵심 패키지들(애플리케이션 동작과 연관된) 설치(dependencies)
dependencies 는 일반적으로 npm install 라이브러리명 으로 설치
react, react-dom, react-router-dom 설치
npm install react react-dom react-router-dom
package.json에 다음과 같이 dependencies가 추가된 것을 확인할 수 있다.
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "webpack serve --mode development --open --hot",
"build": "webpack --mode production"
},
"author": "",
"license": "ISC",
// dependencies에 리액트 패키지들이 추가됨
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0"
"react-router-dom": "^6.4.3"
}
}
- package.json script 기본 설정
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
- package.json script 부분에서 test를 웹팩 사용을 위해 dev로 변경해 준다. 설정한 dev 명령어로 사용 가능하다.
--mode 옵션은 번들링 진행 상태를 보여준다. > --mode development --open --hot
"scripts": {
"dev": "webpack serve --mode development --open --hot",
"build": "webpack --mode production"
},
3. 개발에 필요한 라이브러리들(애플리케이션 동작과는 직접연관이 없지만 개발할 때 필요한)설치(devDependencies)
바벨(Babel) 설치
devDependencies 는 npm install 라이브러리명 --save-dev 혹은 npm install 라이브러리명 -D 로 설치
리액트에서는 ES6와 JSX를 사용한다. 바벨은 브라우저 호환성을 위해 ES6 상위 버전을 => ES5 버전, JSX => js로 트랜스파일링을 해준다. 즉 ES6의 최신 문법 코드가 일부 실행 환경에서 작동하지 않는 이슈에 대하여 ES6 이상의 최신 문법으로 작성한 자바스크립트 코드를 ES5 이하의 예전 문법으로 작성한 것 처럼 소스 코드 내의 문법의 형태를 변경해 주어 모든 환경에서 돌아가도록 호환시켜준다는 것이다.
npm install @babel/core @babel/preset-react @babel/preset-env -D
- @babel/core : 바벨의 코어
- @babel/preset-react : 리액트 JSX를 트랜스파일링
- @babel/preset-env : ES6코드를 ES5로 트랜스파일링
- 설정
루트 경로에서 babel.config.js 파일을 생성하고 프리셋들을 설정
- babel.config.js
module.exports = {
presets: ['@babel/preset-react', '@babel/preset-env'],
};
4. 웹팩(Web pack) 설치
모듈 번들러인 웹팩의 핵심 패키지들 설치
npm install webpack webpack-cli webpack-dev-server -D
- webpack : 웹팩의 코어
- webpack-cli : 웹팩을 커맨드라인에서 사용
- webpack-dev-server : 웹팩을 메모리 상에 빌드하여 개발 서버를 구동
5. 로더 설치
웹팩 번들링에 필요한 로더들을 설치
npm install babel-loader style-loader css-loader file-loader -D
- babel-loader : JSX 및 ES6+ 문법을 트랜스파일링
- style-loader : 변환된 CSS 파일을 <style> 태그로 감싸서 삽입
- css-loader : CSS 파일을 자바스크립트가 이해할 수 있도록 변환
- file-loader : 이미지 및 폰트 등의 파일 로딩
6. 플러그인 설치
웹팩 번들링 후 적용할 플러그인 설치
npm install html-webpack-plugin clean-webpack-plugin -D
- html-webpack-plugin : HTML 파일에 번들링된 자바스크립트 파일을 삽입해주고 번들링된 결과가 저장되는 폴더에 옮김.
- clean-webpack-plugin : 번들링을 할 때마다 이전 번들링 결과를 제거.
- mini-css-extract-plugin : css 파일로 변환해주는 플러그인.
7. 웹팩 설정
루트 경로에 webpack.config.js 파일을 생성한다.
- webpack.config.js
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
module.exports = {
mode: process.env.mode,
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "dist"),
filename: "[hash].js",
publicPath: "/",
},
- mode : devlopment(개발용), production(배포용), none 3가지 모드가 있다.
- entry : 웹팩을 실행할 대상 파일
- output : 웹팩의 결과물에 대한 정보를 입력하는 속성
resolve: {
// path.resove 형태로 사용할 수도 있다.
// 그러면 node의 기본 모듈 'path'를 불러와야 한다.
extensions: [".js", ".jsx", ".css"],
},
- resolve : 웹팩이 모듈을 처리하는 방식을 설정하는 속성으로 확장자를 생략해도 인식하게 만든다.
- devtool : source-map을 설정하는 부분으로 에러가 발생했을 때 번들링된 파일에서 어느 부분에 에러가 났는지를 쉽게 확인할 수 있게 해주는 도구(생략)
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules/",
loader: "babel-loader",
},
{
test: /\.css$/,
use: [
{
loader: "style-loader",
},
{
loader: "css-loader",
},
],
},
],
},
- modules, rules : 모듈에 적용할 로더들과 그 옵션들을 설정
test : 어떤 파일에 적용할지 확장자 작성
exclude : 로더에서 제외할 파일 설정
loader : 적용할 로더가 1개라면 loader로 설정
use : 적용할 로더가 2개 이상이면 use 배열로 설정
const htmlWebpackPlugin = require('html-webpack-plugin');
const cleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
...
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html",
}),
],
- 플러그인 적용 : 설치했던 플러그인을 불러와 설정해 준다.
html-webpack=plugin의 template는 번들링 파일을 주입하고 번들링 폴더로 복사할 대상 HTML 파일을 명시하는 옵션이다.
devServer: {
host: "localhost",
port: 3000,
hot: true,
open: true,
},
};
- devServer : webpack-dev-server의 옵션 설정
overlay : 에러 발생 시 브라우저에 내용을 띄울지 설정
hot : 모듈의 변화만 자동으로 로드하는 HMR(Hot Module Replacement) 기능 활성화 설정
writeToDisk : 메모리 뿐만 아니라 파일도 만들것인지 설정
전부 설치 시, packeage.json의 devDependencies 에 다음과 같이 추가된다.
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.0",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.2",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
전체 package.json 코드
{
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"author": "",
"license": "ISC",
"scripts": {
"dev": "webpack serve --mode development --open --hot",
"build": "webpack --mode production"
},
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.3"
},
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
"@babel/preset-react": "^7.18.6",
"babel-loader": "^9.1.0",
"clean-webpack-plugin": "^4.0.0",
"css-loader": "^6.7.2",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.75.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
dependencies와 devDependencies이 구분되어 관리하는 이유
dependencies 에는 애플리케이션 동작과 연관된,
devDependencies 에는 애플리케이션 동작과 직접적인 연관은 없지만, 개발할 때 필요한 라이브러리를 설치한다.
이렇게 구분해주는 이유는 결국 배포할 때 어떤 라이브러리가 포함되냐 이다.
dependencies 에 설치된 라이브러리는 배포할 때 포함되지만
devDependencies 에 설치된 라이브러리는 개발할 때 필요한 라이브러리기 때문에 배포할 때 포함되지는 않는다.
이렇게 잘 구분을 해서 설치해줘야 빌드시간도 줄이고, 배포할 때 불필요한 라이브러리를 포함시키지 않아도 된다.
8. 리액트 컴포넌트 생성
1. public 파일 생성 후 index.html 생성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CRA 없이 리액트 개발 환경 구축</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
2. src 파일 생성 후 App.jsx 생성
import React from 'react';
import './App.css';
const App = () => {
return <div className='container' />;
};
export default App;
3. root의 index.js 생성
import React from 'react';
import ReactDom from 'react-dom';
import App from './App';
ReactDom.render(<App />, document.getElementById('root'));
위의 모든 과정이 완료 된 후 파일 구조
마지막으로 실행하기
package.json에서 설정한 script 명령어로 npm 실행시키기
npm run dev
< 참고 >
'JavaScript > React' 카테고리의 다른 글
[SCSS] 온보딩 3주 2일차 - SCSS 설치 및 사용해 보기 (0) | 2023.03.21 |
---|---|
[React] 리액트 라우터(react-router-dom) 중첩 라우팅으로 하위페이지 연결하기 - nested routing, outlet (0) | 2022.11.24 |
[React] 웹팩(Webpack)에 대한 이해 (0) | 2022.11.18 |
[React] UUID - Date.now(), random()없이 고유한 key값 생성하기 (0) | 2022.11.06 |
[React]리액트(React)에서 벡터이미지(SVG)사용하는 방법 (0) | 2022.10.30 |