webpack과 babel 리액트 프로젝트 생성Frontend/webpack & babel2022. 6. 4. 14:49
Table of Contents
webpack?
- 웹팩은 엄청 많이 쓰이는 오픈 소스 모듈 번들러 라이브러리이다.
- 번들러(Bundler)?
번들러는 여러 개로 나뉜 모듈을 하나로 묶어주는 도구이다.
의존성이 있는 것들을 찾아서 그룹핑을 해주는 도구! - 웹팩은 IIFE를 사용해서 번들링을 해서 스코프 충돌에 대한 걱정 없이 안전하게 스크립트 파일들을 연결하거나 결합한다!
- dependency graph를 생성하여 빌드
- 번들러(Bundler)?
- 거대한 자바스크립트 소스코드와 대규모 의존성을 가지고 있는 대형 웹 애플리케이션이 등장함에 따라, 각각의 세분화된 모듈 파일이 무작위로 늘어나게 되었다.
- 이 모듈 단위의 파일들을 호출하여 브라우저에 띄워야 하는데, 자바스크립트의 특성에 따라 발생하기 쉬운 각 변수들의 스코프 문제를 해결해야 하고, 각 자원을 호출할 때 생겨나는 네트워크 쪽의 코스트도 신경써야 한다!
사용하지 않을 때 문제점
1. 글로벌 환경으로 실행되기 때문에 변수 충돌의 가능성
- 아래처럼 lodash를 글로벌 환경으로 로딩한 후 div 태그 안에 Hello World 텍스트를 넣어서 body 태그 안에 넣는 자바스크립트 파일을 만든 후 body 태그 안에 넣어보자.
- 대부분의 페이지 방식의 php, jsp, asp 같은 서버사이드 렌더링에서 사용하는 방식이다.
index.js
function component() {
let element = document.createElement('div');
element.innerHTML = _.join(['Hello', 'World'], ' ');
return element;
}
document.body.appendChild(component());
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>webpack demo</title>
<script src="https://unpkg.com/lodash@4.16.6"></script>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
- lodash에서 _ 변수를 사용하는데 두번째 이후로 로딩하는 자바스크립트 파일에서 만약 _ 를 다시 정의하면 변수의 충돌이 발생해서 오작동이 일어난다!
- 실제로 jquery에서 사용하는 $는 다른 라이브러리에서 많이 사용되기 때문에 충돌이 일어날 수도 있다!
- 위와 같은 문제를 해결하기 위해서 네임스페스 패턴이나 IIFE 패턴을 사용하여 충돌을 피하는 방법을 사용하게 된다.
2. 로딩 순서 의존성
- 만약 아래처럼 jquery와 jquery 로딩 순서를 바꿨다고 해보자
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>webpack demo</title>
<script src=”//code.jquery.com/ui/1.12.1/jquery-ui.js”></script>
<script src=”//code.jquery.com/jquery-1.12.4.js”></script>
</head>
<body>
</body>
</html>
- 위처럼 순서를 바꾸면 오류가 발생한다!!
- 왜냐하면 jquery-ui가 jquery를 사용하기 때문이다 → 의존성이 있기 때문에 jquery가 먼저 로딩 되어야 한다.
- 이 부분이 모듈 환경으로 넘어간다면 npm이 jquery-ui를 먼저 설치하더라도 의존성이 있는 파일을 알아서 먼저 설치해주기 때문에 의존성을 해결할 수 있다!
3. 로딩 문제
- 페이지가 바뀔 때마다 이전 페이지에서 로딩했던 동일한 자바스크립트 파일들이 대부분 다시 로딩되어져야 한다.
- 모바일이 등장하면서 페이지가 바뀔때 마다 많은 자바스크립트와 css가 로딩이 되는것은 네트워크 트래픽 증가와 속도의 저하를 가져오게 되면서 SPA 프레임웍이 등장하게 된다.
babel?
- babel은 브라우저가 지원하지 않는 자바스크립트 문법들을 부라우저가 이해할 수 있도록 코드를 변환하는 역할을 한다. → 컴파일러
- 특정 브라우저에서 지원하지 않는 es5,es6, 리액트에서 사용하는 jsx등 차세대 자바스크립트 문법 등을 브라우저가 이해할 수 있도록 바꿔준다
loader & plugin
- 자세한 loader와 plugin 사용법및 종류는 아래 블로그를 꼭 참고하자!
- https://yamoo9.gitbook.io/webpack/webpack/config-webpack-dev-environment
loader
- 로더는 빌드 도구를 통한 빌드 과정에서 각 파일을 import 혹은 load할 때 모듈의 소스코드를 변형시키는 전처리 과정을 수행
- Typescript 같은 다른 언어를 Javascript로 변환하고, image를 data url로 바꾸며, css파일의 import를 JS코드로 옮길 수 있음
- webpack은 기본적으로 JS / JSON 파일만 이해할 수 있어서, other type의 파일을 convert 해줘야 한다
- webpack은 모든 것을 하나의 모듈로 처리 (CSS파일, JS파일 등등)
- webpack에서 로더의 적용은 배열 뒤 -> 앞 방향으로 적용한 순서대로 실행
- 번들링된 결과에 hash값을 붙이는 것은, 브라우저가 로컬 캐시로 이전 데이터를 바라보지 않게 하기 위함
- 빌드할 때 clean-webpack-plugin 플러그인을 통해 해시값이 바뀌면서 불필요하게 쌓이는 빌드 파일을 없앨 수 있다
plugin
- Loader가 파일 단위로 처리하는 반면, Plugin은 번들링된 결과물을 처리
- Loader는 함수로 정의하지만, Plugin은 클래스로 정의
- Plugin은 bundle optimization / asset management / injection of environment 등으로 활용 가능
webpack 설정하기
모듈 저장소 만들기
1. 프로젝트를 만들 디렉토리에 프로젝트 폴더를 생성
mkdir webpack_babel
2. 프로젝트 경로로 이동
cd webpack_babel
3. 프로젝트 구조용 폴더 src와 public 생성하기
mkdir -p src public
4. package.json 파일 작성
- 아래 명령어를 수행하면 package.json 파일이 만들어졌을 것이다. 이 파일은 모듈방식 개발에서 가장 중요한 파일 환경이다.
- 이제부터 설치하는 모든 모듈들은 node_modules에 저장되고 그 정보는 package.json에 기록된다!
# -y 자동으로 모든 물음에 빈칸으로 응답할 수 있다.
yarn init -y
5. webpack 설치하기
- -D와 --dev 옵션을 사용해서 devDependencies로 사용하는 이유는 개발 중에만 사용하고 실제 운영할 때는 사용하지 않기 때문!
- dependencies는 애플리케이션 동작과 연관된, devDependencies는 애플리케이션의 동작과 직접적인 연관은 없지만, 이름 그대로 개발할 때 필요한 라이브러리를 설치
- 구분하는 이유는 배포할 때, 어떤 라이브러리가 포함될 것이냐의 여부이다!
- webpack
→ 웹팩의 코어 - webpack-cli
→ 웹팩을 커맨드라인에서 사용
yarn add -D webpack webpack-cli
yarn add webpack webpack-cli --dev
6. index.html 파일 생성
- public 폴더 아래 index.html 파일을 추가하자
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root">Webpack and babel</div>
</body>
</html>
7. package.json에 build 명령어 추가
package.json
"scripts": {
"build" : "webpack --mode production",
}
webpack 설정 (Javascript)
- webpack.config.js 파일을 하나 만들어야한다.
webpack.config.js
- mode: 개발 환경인지 배포된 환경인지 써둠
- entry: 파일을 묶기 위해 webpack이 바라보는 시작 파일을 명시
- output: bundle된 파일의 결과물을 위한 설정. 어떤 이름으로 할지 경로를 어디로 할지 명시.
- resolve: import될 수 있는 파일의 확장자 명을 적어둠
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"] },
stats: { children: true }
};
- 여기까지 설정은 webpack의 동작을 정의했고 Javascript에 대한 동작만 담겨있다. 하지만 프로젝트 결과는 Js뿐만 아니라 HTML, CSS도 포함되어 있다.
- 만약 여기까지
webpack loader/plugin 설치 (HTML)
- html-webpack-plugin
→ HTML에 번들링한 JS 파일을 삽입하고, HTML파일을 번들링 된 결과물이 저장될 폴더에 옮겨준다. - clean-webpack-plugin
→ webpack에 의해 빌드 된 결과물을 자동으로 정리하는 플러그인. 다시 빌드한 후 webpack의 output.path 디렉토리에 있는 모든 파일과 사용하지 않는 웹팩 자산을 제거한다!
yarn add -D html-webpack-plugin clean-webpack-plugin
webpack loader/plugin 설치 (CSS)
- mini-css-extract-plugin
→ 플러그인은 CSS 파일을 별도 파일로 추출(extract) 한다.
→ CSS 코드가 포함된 JS 파일 별로 CSS 파일을 생성한다.
→ CSS 및 SourceMaps의 온 디멘드 로딩(On Demand Loading)을 지원한다 - css-loader
→ Js 파일에서 css 파일을 불러오기 위해 사용하는 로더
→ 내부적으로 번들링된 js 파일에 string 값으로 css 데이터들이 존재하게 된다
→ mini-css-extract-plugin과 함께 사용한다
→ 혹은 style-loader와 함께 사용해서 실제 dom으로 추가해서 css를 반영한다. - sass-loader
→ Sass / SCSS 파일을로드하고 CSS로 컴파일 - file-loader
→ 이미지 같은 파일(file)을 가져오는 코드를 해석하고 로드하는 목적으로 사용
yarn add -D mini-css-extract-plugin css-loader sass-loader file-loader
※ 참고사항 style-loader vs mini-css-extract-plugin
- style-loader
→ css-loader를 통해 웹팩 의존성 트리에 존재하게 되는 css 코드를 브라우저에 적용해주는 로더
→ 웹팩 의존성 트리에 추가된 string 값들을 돔에 <style></style> 로 넣어준다. - style-loader와 mini-css-extract-plugin을 함께 사용하면 안된다!
- mini-css-extract-plugin은 Javascript 파일 안에서 호출되는 스타일 코드를 chunk에서 파일로 개별 추출하므로 개발 중에는 플러그인을 사용하지 않는 것이 좋다. 즉, 배포할 때 사용하면 좋다.
- 개발 모드에서는 CSS를 여러번 수정하고 DOM에 <style> 요소의 코드로 주입하는 것이 훨씬 빨리 작동하므로 style-loader를 사용한는 것이 더 낫다
webpack.config.js 설정
- 위처럼 필요한 loader와 plugin을 설치 했다면 webpack.config.js 파일을 아래처럼 설정하자!!
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')
},
resolve: { extensions: ["*", ".js", ".jsx"] },
stats: { children: true },
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']
}
]
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'webpack-react-start-kit',
template: './public/index.html'
}),
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
}),
]
};
babel 설정하기
babel 설치하기
# @babel/core : 바벨 코어 라이브러리
# babel-loader : webpack에 babel 적용하기 위한 라이브러리
# @babel/preset-env : es6를 es5로 컴파일링 해주는 라이브러리
# @babel/preset-react : JSX를 자바스크립트 코드로 변환해주는 라이브러리
yarn add -D @babel/core babel-loader @babel/preset-env @babel/preset-react
babel 설정하기
- .babelrc 파일을 만들고 아래 내용을 추가하자
.babelrc
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
webpack & babel 연동하기
- webpack.config.js 파일에서 module 아래 rules에 아래 내용을 추가한다!
...
module.exports = {
...
module: {
rules: [
...
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
]
},
...
};
리액트 프로젝트 생성하기
1. 리액트 설치하기
yarn add react react-dom
2. index.js 만들기
- webpack.config.js 파일에서 entry를 ./src/index.js로 지정했으므로 src 폴더 아래 index.js 파일을 생성하자.
src/index.js
import React from "react";
import ReactDOM from "react-dom";
// react v18
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<div>webpack & babel</div>);
// react v17
// ReactDOM.render(<div>webpack & babel</div>, document.getElementById("root"));
3. webpack-dev-server 설정하기
- webpack-dev-server는 빠른 실시간 리로드 기능을 갖춘 개발 서버로, 디스크에 저장되지 않는 메모리 컴파일을 사용하기 때문에 컴파일 속도가 빨라짐
- webpack.config.js에도 devServer 옵션을 통해 옵션을 지정하여 사용이 가능
webpack-dev-server 설치
yarn add webpack-dev-server
webpack.config.js 설정 추가
- webpack.config.js 파일에 아래 devtool, devServer 내용을 추가하고 그 아래 plugins에 new webpack.HotModuleReplacementPlugin()를 추가하자
...
module.exports = {
...
module: {
...
devtool: "inline-source-map",
devServer: {
static: {
directory: path.join(__dirname, 'public'),
},
compress: true,
port: 9000,
},
plugins: [
...
new webpack.HotModuleReplacementPlugin(),
]
};
4. 시작 커맨드 추가
- package.json에 start 커맨드를 추가하자.
// package.json
"scripts": {
...
"start": "webpack-dev-server"
},
- 여기까지 설정을 하고 yarn start 명령어를 사용하면 잘 실행되는 모습을 볼 수 있다!
yarn start
전체 소스코드
https://github.com/ejzl521/webpack_babel_react
'Frontend > webpack & babel' 카테고리의 다른 글
webpack으로 React 프로젝트 빌드해보기 =) (0) | 2023.10.08 |
---|---|
Babel (0) | 2023.10.08 |
Loader / Plugin (1) | 2023.10.08 |
Entry(index.js) / Output (0) | 2023.09.03 |
webpack (1) | 2023.08.21 |
@덕구공 :: Duck9s'
주니어 개발자에욤
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!