티스토리 뷰
리액트 공부 중 웹팩 설정 부분을 자꾸 까먹어 내용을 따로 정리하게 되었습니다.
웹팩이 무엇이고 왜 사용하는지를 다루지 않습니다. 어떻게 웹팩을 설정하고 리액트와 함께 사용할 수 있는지에 대해 다룹니다.
초심자 입장에서 쓴 글이니 더 깊은 내용을 원하시는 분들은 다른 문서를 참조해주시면 감사하겠습니다.
해당 포스트는 조현영 님의 웹 게임을 만들며 배우는 리액트 강의와 webpack 공식 문서를 참고하여 작성했습니다.
1. npm 패키지 설치
우선 react, react-dom을 설치해 줍니다.
npm i react react-dom
webpack 관련 패키지를 개발용으로 설치해줍니다.
npm i -D webpack webpack-cli
ECMA2015 이후 문법과 jsx 문법을 사용하기 위해 babel 관련 패키지도 개발용으로 설치해줍니다.
npm i -D @babel/core @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties babel-loader
@babel/core : 이름 그대로 바벨 코어입니다. 필수
@babel/preset-xxx : preset은 plugin의 집합입니다.
@babel/preset-env: babel의 지원범위를 설정, 타깃 브라우저를 입력하면 사용자 환경에 맞춰 최신 ES를 사용할 수 있게 해줍니다.
@babel/preset-react: react 환경을 위한 프리셋입니다.
@babel/plugin-proposal-class-properties: class에서 state를 사용하려면 필요하다고 합니다
babel-loader: 바벨과 웹팩을 연결해줍니다.
2. 모듈 시스템과 웹팩 설정
index.html
<body></body> 사이에 다음 코드를 삽입합니다.
<body>
<div id="root"></div>
<script src="./dist/app.js"></script>
</body
client.jsx
여러 컴포넌트들을 각각 모듈화 하고, client.jsx에서 불러와 렌더링 해줍니다.
const React = require('react');
const ReactDom = require('react-dom');
const YourComponent = require('./YourComponent');
ReactDom.render(<YourComponent />, document.querySelector('#root'));
webpack.config.js
객체 하나를 exports 하도록 합니다. 모든 옵션을 하나의 코드로 보면 너무 헷갈리니까 부분 부분 쪼개어 설명합니다.
module.exports = {
...
};
- name, mode, devtool
name : 여러 개의 설정을 불러와야 할 때 사용한다고 합니다.
mode : webpack이 어떤 최적화를 해야 할지 알려줍니다. 'development', 'production' 두 인자를 줄 수 있고 각 모드에 맞춰 최적화합니다.
devtool : https://perfectacle.github.io/2016/11/14/Webpack-devtool-option-Performance/ 이 블로그에서 잘 설명해뒀습니다. 참고하시면 될듯해요.
name: 'number-baseball', // 필수는 아님
mode: 'development', // 실서비스시 'production'
devtool: 'eval'
- entry
entry, output 속성이 핵심입니다. entry는 입력, output은 출력이라고 생각하면 됩니다.
여러 파일들을 하나로 모아 index.html에서 부를 수 있는 "./dist/app.js"를 만들어야 합니다.
entry 속성에 빌드할 파일을 명시해줍니다.
entry: {
// client.jsx에서 다른 jsx파일을 import하므로 그 파일들은 써줄 필요 없음
app: ['./client.jsx'],
},
- resolve
entry에서 파일이 많아지면 확장자를 쓰기 귀찮습니다. resolve 속성에 관련된 확장자를 추가하여 다음처럼 쓰면 웹팩이 알아서 찾아줍니다.
resolve: {
extensions: ['.js', '.jsx'],
},
entry: {
// 확장자 쓸 필요 없음
app: ['./client'],
},
- output
빌드 결과로 dist폴더 내에 app.js를 만들어야 합니다. path 모듈을 불러와 다음처럼 설정합니다.
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js',
},
- loader
loader는 모듈의 소스 코드에 적용되는 변환이라고 합니다. (무슨 말인지 이해 못했습니다..) entry 파일에 babel을 적용하기 위해 babel-loader를 설정해야 합니다.
module이라는 속성을 이용해 적용할 수 있습니다.
module: {
rules: [
{
test: /\.jsx?/, // 정규표현식, .js .jsx 파일에 적용하겠다는 뜻
loader: 'babel-loader',
options: {
presets: [
['@babel/preset-env',
{
targets: {
browsers: ['> 5% in KR'],
},
debug: true,
},],
'@babel/preset-react',
],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
],
},
rules: 여러 종류의 로더를 설정할 수 있습니다. 따라서 배열을 사용합니다.
├─ test: loader를 적용할 파일 확장자를 뜻합니다. 위 설정에선 정규 표현식을 사용해 .js, .jsx를 나타내었습니다.
├─ loader: 적용할 loader의 종류입니다. babel-loader를 적용해 웹팩이 바벨을 해석할 수 있게 해 줍니다.
└─ options: 바벨의 옵션을 넣어줍니다. 아마 웹팩과 무관한 설정으로, 이 경우엔 바벨 자체의 옵션을 뜻하는 것 같습니다. 따라서 웹팩을 이해하기 위해 필수적인 요소는 아닙니다. 위 옵션들은 나중에 바벨 관련된 포스팅을 따로 파서 설명하겠습니다.
- plugins
webpack에서 부가적으로 설정할 수 있는 플러그인들입니다. 여러 종류가 있습니다.
plugins: [new webpack.LoaderOptionsPlugin({ debug: true })],
- 완성된 설정 파일
결과적으로 다음과 같은 webpack.config.js 파일을 작성했습니다.
한꺼번에 보면 정말 복잡해 보이지만 속성 하나하나를 쪼개어 보면 전혀 어렵지 않다는 걸 알 수 있습니다.
const path = require('path');
const webpack = require('webpack');
module.exports = {
name: 'number-baseball',
mode: 'development',
devtool: 'eval',
resolve: {
extensions: ['.js', '.jsx'],
},
entry: {
app: ['./client'],
},
module: {
rules: [
{
test: /\.jsx?/,
loader: 'babel-loader',
// babel 옵션
options: {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['> 5% in KR'],
},
debug: true,
},
],
'@babel/preset-react',
],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
],
},
plugins: [new webpack.LoaderOptionsPlugin({ debug: true })],
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js',
},
};
3. 웹팩으로 빌드하기
웹팩 실행
두 가지 방법으로 웹팩을 실행할 수 있습니다.
1) package.json의 script 추가
package.json 에 다음 코드를 삽입합니다.
{
...
"scripts": {
"dev": "webpack"
},
...
}
그 후 다음처럼 실행합니다.
npm run dev
2) npx
혹은 다음 명령어로 바로 실행합니다.
npx webpack
이후 웹팩을 실행하면 dist 폴더 내에 하나의 통합 파일인 app.js가 생성됩니다.
이제 index.html에서 app.js를 불러와 실행할 수 있습니다!
4. webpack-dev-server, react-hot-loader
파일을 수정할 때마다 웹팩을 실행하기가 여간 귀찮은 게 아닙니다.
다음 두 패키지를 이용하면 편하게 로컬 서버를 제공해주고, 내 코드의 변경점을 감지하여 자동으로 업데이트해줍니다.
webpack-dev-server
webpack.config.js를 읽어 빌드하고, 로컬 서버를 제공합니다.
react-hot-loader
.jsx 파일이 수정될 때 자동으로 업데이트해주는 거 같은데 정확히는 모르겠습니다. 어느 정도 숙달이 됐을 때 자세히 알아보도록 하겠습니다.
npm 패키지 설치
다음 두 패키지를 개발용으로 설치해줍니다.
npm i -D react-hot-loader webpack-dev-server
기존 설정에서 변경점
package.json
scripts - dev를 다음과 같이 수정합니다.
"scripts": {
"dev": "webpack-dev-server --hot"
},
client.jsx
3, 6, 8번째 줄이 변경되었습니다.
const React = require('react');
const ReactDom = require('react-dom');
const { hot } = require('react-hot-loader/root');
const YourComponent = require('./YourComponent');
const Hot = hot(YourComponent);
ReactDom.render(<Hot />, document.querySelector('#root'));
webpack.config.js
babel-loader 옵션의 plugin을 추가합니다. 21번째 줄을 확인해주세요.
module: {
rules: [
{
test: /\.jsx?/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['> 5% in KR'],
},
debug: true,
},
],
'@babel/preset-react',
],
plugins: [
'@babel/plugin-proposal-class-properties',
'react-hot-loader/babel',
],
},
},
],
},
또한 output 속성에서 publicPath를 지정해주어야 웹팩 데브 서버가 해당 폴더에 app.js를 생성합니다.
이와 관련해서는 나중에 이해도가 높아지면 좀 더 공부해보도록 하고 일단은 하라는 대로 해보겠습니다.
output: {
path: path.join(__dirname, 'dist'),
filename: 'app.js',
publicPath: '/dist/',
},
모든 설정을 끝내고 로컬 서버로 접속하면 코드를 수정하고 저장할 때마다 브라우저 화면이 변경되는 것을 볼 수 있습니다.
'개발 > 환경 설정' 카테고리의 다른 글
[NPM] npm scripts를 현재 디렉토리 기준으로 실행하는 방법 (2) | 2021.05.20 |
---|