웹팩과 리액트
리액트 개발에 꼭 필요한 라이브러리
1. react, react-dom
너무나 당연한 이야기지만, 리액트 컴포넌트와 Hooks, 라이프 사이클에 대한 정보가 모두 들어있는 리액트와 이 리액트 코드를 브라우저에 보여줄 수 있는 react-dom은 꼭 필요하다.
2. babel
React를 학습하기 전, JSX부터 배워야 했었다. 그런데, 브라우저에서 JavaScript는 읽을 수 있지만 JSX는 읽을 수 없다. 지금까지 React를 JSX로 작성해왔는데브라우저에서 내가 만든 React 애플리케이션을 볼 수 있었던 이유는 create-react-app에 포함되어 있는 babel이 jsx를 js로 변경해주어 번들링을 해줬기 때문이다. 참고로 babel은 JSX를 JavaScript로 변경하여 entry에서 불러올 수 있게 만들어줬기 때문에 로더의 일종으로 볼 수 있겠다.
3. css-loader
create-react-app으로 만들어진 애플리케이션을 보면 import 'aaa.css' 와 같이 입력해도 CSS가 적용되던 것을 알 수 있다. css-loader가 필요하다는 것을 쉽게 알 수 있다.
리액트 개발에 도움이 되는 라이브러리
1. react-hot-reloader
react-hot-reloader는 webpack-dev-server처럼 저장할 때 마다 변경사항을 개발 환경에 적용해주는 라이브러리이다. react-hot-reloader는 리액트 상태를 유지시켜준다.
2. eslint
eslint는 JavaScript로 개발 시 자주 접하는 에러를 방지하기 위한 린터이다. eslint 역시 많은 config와 plugin이 있는데, 이를 잘 조합하면 리액트에서 자주 접하는 에러를 미리 발견하는데 도움이 된다.
3. prettier
prettier는 JavaScript로 개발 시 통일성 있게 코드 형식을 맞출 수 있게 도와주는 툴이다. eslint와 조합해서 통일된 코드 형식까지 강요할 수도 있다.
과제 : 리액트 웹앱 번들링하고 배포하기
1. package.json 생성
npm init -y
2. 리액트 관련 라이브러리 설치
npm install -D react react-dom
- react : 리액트 컴포넌트와 Hooks, 라이프 사이클에 대한 정보가 들어있는 코어 라이브러리
- react-dom : 리액트와 DOM 연결
3. 웹팩 관련 라이브러리 설치
npm install -D webpack webpack-cli webpack-dev-server html-webpack-plugin
- webpack-cli : 터미널에서 웹팩 명령어 실행 가능하게 해줌
- webpack-dev-server : 파일 변경사항 실시간으로 빌드하는 개발 서버 구동 (dev 서버)
- html-webpack-plugin : html 파일에 번들링 된 js 파일을 삽입
4. 바벨 관련 라이브러리 설치(바벨도 로더에 포함되는 개념)
npm install -D babel-loader @babel/cli @babel/core @babel/preset-env @babel/preset-react
- babel-loader : 바벨 설정 파일(babel.config.js)을 읽어 해당 설정에 맞게 변환. 바벨과 웹팩을 연결.
- @babel/cli : 터미널에서 바벨명령어 사용가능하도록 CLI 제공
- @babel/core : babel의 핵심기능을 포함해서 반드시 설치해야 함
- @babel/preset-env : ES6+ 코드를 ES5 코드로 변환시켜줌
- @babel/preset-react : 리액트(JSX)를 js로 인식가능
5. 최상위에 babel.config.js 또는 .babelrc 생성
module.exports = {
presets: [
['@babel/preset-env'],
['@babel/preset-react', { runtime: 'automatic' }],
],
}
6. 로더 라이브러리 설치 (babel, html, css, style)
npm install -D css-loader style-loader
- css-loader : CSS를 JS파일 내에서 불러올 수 있게 함
- style-loader : CSS를 DOM(style 태그) 안에 담아줌
7. webpack.config.js 생성
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: 'app.bundle.js',
path: path.resolve(__dirname, 'docs'),
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: "babel-loader",
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
})
]
};
8. docs/index.html 열어서 확인해보기
서버를 안켜서 밑부분은 안나오지만, 정상적으로 번들링 된 것은 확인할 수 있다.
npm run start를 했을 때 흰 화면만 나오고 에러가 떠서 내가 번들링 과정에서 뭔가를 실수한 줄 알고 정말 애를 많이 먹었다 ㅠㅠ 이것때문에 한시간 넘게 삽질했다...관련 stackoverflow 글을 거짓말안치고 다 읽어본 것 같다.. 하지만 적용이 1도안됐다^^7
왜냐?!?!?!
구글링해보니 번들링 후에는 index.html을 확인해봐야하는 것이였다..(두둥) 어제 바닐라J로만 작성되어있던 웹앱을 번들링했을 때처럼!
저 화면을 보고 안도의 한숨을 내쉬었다... 기가 다 빨린 느낌~!
여하튼 오늘 과제는 튜토리얼없이 처음부터 혼자서 해야해서'리액트 웹팩으로 시작하기', '리액트 웹팩 실행' 등등 구글링을 정말 열심히했다!!!! 와우~!!
작동 Mode 설정 - dev, prod
개발 development mode와 배포 production mode에 따라 config file을 나누기
1. base에 dev나 prod 합치기 위해 webpack merge 설치
npm i -D webpack-merge
2. webpack.config.js를 3개로 분할
webpack.config.base.js를 기준으로 +dev나 +prod 하는 구조
webpack.config.js --> webpack.config.base.js 로 변경
webpack.config.dev.js
webpack.config.prod.js
3. 각 파일 생성 후 작성
//webpack.config.dev.js
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.config.base");
module.exports = merge(baseConfig, {
mode: "development",
devServer: {
port: 3001,
},
});
//webpack.config.prod.js
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.config.base");
module.exports = merge(baseConfig, {
mode: "production",
});
4. package.json 추가
// package.json
"scripts": {
"build": "webpack --config webpack.config.prod.js",
"dev": "webpack-dev-server --open --config webpack.config.dev.js"
},
Output 관리
1. 번들링 할 때 마다 디렉터리를 정리하기 (참고 링크)
- output에 clean: true 추가
// webpack.config.js output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'docs'), clean: true, },
2. 번들파일명 동적으로 생성하기 - [name].bundle.js
// webpack.config.js
output: {
filename: '[name].bundle.js',
},
Asset 관리 - CSS에 minify 적용
- style-loader
: css파일을 style태그로 만들어 head안에 넣어준다. 대신에 mini-css-extract-plugin 사용하기도 한다.
- mini-css-extract-plugin : CSS 파일을 별도 파일로 추출(extract)한다. CSS 코드가 포함된 JS 파일 별로 CSS 파일을 생성한다.
- css-minimizer-webpack-plugin : CSS를 최적화(압축)한다.
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'docs'),
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: "babel-loader",
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'], // 수정
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
})
],
optimization: { // 여기부터 추가
minimizer: [new CssMinimizerPlugin()],
},
};
개발용 서버
webpack-dev-server처럼 저장할때마다 변경사항을 적용시며주고, 리액트의 상태를 유지해주는 플러그인 설치한다.
react-refresh-webpack-plugin
npm i -D @pmmmwh/react-refresh-webpack-plugin react-refresh
webpack.config.dev.js 수정
// webpack.config.dev.js
const { merge } = require("webpack-merge");
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const baseConfig = require("./webpack.config.base");
module.exports = merge(baseConfig, {
mode: "development",
devServer: {
port: 3000,
hot: true,
},
plugins: [new ReactRefreshPlugin()]
});
eslint 설치
코드에 문제가 없는지 검사하기 위해서 설치한다.
npm install -D eslint eslint-plugin-react @babel/eslint-parser
//pacakge.json scripts에 추가
"lint": "eslink ./src",
웹 접근성에 대해서 지켜야하는 부분을 알려주는 eslint rule을 추가 설치한다.
npm install -D eslint-plugin-jsx-a11y
따로 설정파일을 작성해야 한다.
// .eslintrc.js
module.exports = {
parser: "@babel/eslint-parser",
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:react/recommended",
"plugin:jsx-a11y/recommended",
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: "module",
},
settings: {
react: {
version: "18.2.0",
},
},
plugins: ["react"],
rules: {
"react/react-in-jsx-scope": 0,
"react/jsx-uses-react": 0,
"react/prop-types": 0,
},
};
prettier 설치
코드 형식 통일을 위해 설치한다.
- vscode extension으로 설치하거나, 직접 설치하는 방법이 있다.
npm install -D prettier
//pacakge.json scripts에 추가
"pretty": "prettier --write ./",
따로 설정 파일을 만들어줘야 한다.
// .prettierrc.js
module.exports = {
singleQuote: true,
jsxSingleQuote: true,
};
webpack.config.base.js
const path = require("path");
const HtmlWebPackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
mode: "development",
entry: "./src/index.js",
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'docs'),
clean: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: "/node_modules",
use: "babel-loader",
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader'],
exclude: /node_modules/,
},
],
},
plugins: [
new HtmlWebPackPlugin({
template: './public/index.html',
})
],
optimization: { // 여기부터 추가
minimizer: [new CssMinimizerPlugin()],
},
};
webpack.config.dev.js
const { merge } = require("webpack-merge");
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const baseConfig = require("./webpack.config.base");
module.exports = merge(baseConfig, {
mode: "development",
devServer: {
port: 3000,
hot: true,
},
plugins: [new ReactRefreshPlugin()]
});
webpack.config.prod.js
const { merge } = require("webpack-merge");
const baseConfig = require("./webpack.config.base");
module.exports = merge(baseConfig, {
mode: "production",
});
'코드스테이츠 SEB FE 41기 > Section 별 내용 정리' 카테고리의 다른 글
section4/Unit4/[React] 심화(11/28) (0) | 2022.11.28 |
---|---|
section4/Unit4/[React] 심화(11/25) (0) | 2022.11.24 |
section4/Unit3/[HTML/CSS] 심화(11/23) (0) | 2022.11.23 |
section4/Unit2/[HTML/CSS] 심화(11/22) (0) | 2022.11.22 |
section4/Unit2/[HTML/CSS] 심화(11/21) (0) | 2022.11.21 |