React webpack 설정하기

Yesol Lee·2022년 3월 25일
0

리액트

목록 보기
1/1

인프런 웹 게임을 만들며 배우는 React 강의를 듣고 정리함

javascript 모듈 시스템

이전까지는 각 컴포넌트를 만들 때 마다 html에 새로운 script태그를 생성해 작성했었다. 그런데 한 페이지에 컴포넌트가 엄청나게 많기 때문에 기존 방식으로는 html문서가 너무 길어져서 유지보수가 어렵고 가독성이 떨어진다. javascript에서는 module.exports를 사용해 다른 파일의 객체를 불러올 수 있다.

기본적인 구조는 아래와 같다.

1. 불러오고 싶은 컴포넌트 파일

// npm 객체 불러오기
const React = require('react');
const { Component, useState, useRef } = React;

// hooks
const GuGuDan () => {
  // state 설정
  const [value, setValue] = useState('');
  ...
  
  // 함수 만들기
  const onChange = (e) => {
  	setValue(e.target.value);
  }
  ...
  // ref 사용하기
  const inputRef = useRef(null);
  
  // jsx 리턴
  return (
	// jsx 코드
  );
}

// class 
class GuGuDan extends Component () {
  // 생성자: state 설정
  constructor(props) {
    super(props);
    this.state = { value: '', ... };
  }
  
  // 함수 만들기
  onChange = (e) => {
  	this.setState({
    	value: 'new value',
    });
  }
  
  // ref 사용하기
  input;
  onRefInput = (c) => { this.input = c; }
  
  // jsx 그리기
  render () {
  	return (
    	// jsx 작성
    );
  };
}
  
// module로 만들어서 가져갈 수 있게 하기
module.exports = GuGuDan;

2. 다른 파일 객체를 가져와서 사용할 파일

const React = require('react');
const ReactDom = require('react-dom');
// 다른 파일의 객체 불러오기
const GuGuDan = require('./GuGuDan'); // 현재 위치 기준 가져올 파일 경로

// ReactDom으로 html에 불러온 모듈 객체 넣어주기
ReactDom.render(<GuGuDan />, document.querySelector('#root'));

webpack

  • html script태그의 src로 js파일 연결하는 경우, 1개만 넣을 수 있음 -> module 단위로 쪼개놓은 js(x)파일들 어떻게 통합할까? -> webpack 등장
  • webpack.config.js로 모든 것이 실행됨
  • client.jsx, GuGuDan.jsx로 쪼개진 파일들을 app.js에 통합할 예정
  • 설정 후 webpack으로 빌드하면 app.js에 코드가 자동생성된다. 타인이 알아보기 힘들게 난독화(Code Obfuscating)되어있다.
  • 총 2가지 npm 패키지를 설치한다.
webpack
webpack-cli

webpack.config.js 핵심 구성요소

  1. webpack 기초 설정
  2. entry
  3. module.rules.loader
  4. plugins
  5. output

webpack에서 jsx 사용하기 위해 babel 연결하기

  • react에서 jsx형식 코드를 이해하기 위해 babel을 사용하는데, webpack으로 빌드할 때도 babel에 대한 추가 설정이 필요하다.
  • 총 4가지 npm 패키지를 설치한다.
  • 개발할 때만 필요하니 npm i -D 패키지명으로 설치한다.
@babel/core : 기본바벨
@babel/preset-env : 최신문법을 브라우저가 지원하는 옛날 문법으로 변경해줌
@babel/preset-react : react jsx 지원
@babel-loader : babel과 webpack 연결
  "devDependencies": {
    "@babel/core": "^7.17.8",
    "@babel/preset-env": "^7.16.11",
    "@babel/preset-react": "^7.16.7",
    "babel-loader": "^8.2.4",
    "webpack": "^5.70.0",
    "webpack-cli": "^4.9.2"
  }

webpack.config.js 작성하기

1. npm 모듈 연결

// webpack.config.js

const path = require('path'); // 파일경로 조작하는 내장 라이브러리
// const { webpack } = require('webpack');
// 플러그인에 사용되는 npm 모듈
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin'); 

2. module.exports

// webpack.config.js

// 1. npm 모듈
module.exports = {
	// webpack 세팅 이 안에 작성
};

3. 기초설정-entry-module-output 구조

  • 기본적으론 기초설정-entry-output 구조
  • entry 다음에 module을 설정하면 entry로 들어온 파일들에 전부 module을 적용한 후 output으로 보낸다.
  • 이 구조에서 module.rules 등에 설정이 추가되거나 plugins 등 설정이 추가되면서 webpack.config.js 파일이 굉장히 복잡해진다.
  • 복잡한 구조를 이해하고 싶을 땐 모든 preset, plugin들을 지운 후 webpack을 빌드해보고 에러메시지가 뜰 때마다 하나씩 추가하면 이해하기 쉽다고 한다.
// webpack.config.js
module.exports = {
	name: 'webpack-setting-name',
  	mode: 'development', // 실 서비스 시: production
    devtool: 'eval', // 실 서비스 시: hidden-source-map
    resolve: {
    	extensions: [ '.js', '.jsx'], // entry.app에 불러올 파일 확장자 지정
    },
  
    entry: { // 사용할 모든 파일들. 다른 파일에서 불러와서 사용하는 파일들은 생략
        // GuGuDan.jsx는 client.jsx에서 불러오니 패스
        // resolve.extensions에서 확장자 지정하면 app에서 파일 확장자 생략 가능
    	app: ['./client'], 
    },
    module: {
    	rules: [{
            // 정규표현식 : js, jsx 파일에 룰 적용
        	test: /\.jsx?$/,
            // webpack에서 jsx 읽기 위해 babel dusruf
            loader: 'babel-loader',
            options: {
                // presets: plugin들의 모음
            	presets: [
                	'@babel/preset-env', '@babel/preset-react'
                ],
                // plugin: 추가 기능을 위한 확장 프로그램
                plugins: [], 
            },
        }],
    },
    output: {
        // __dirname: 현재 파일 경로
        // path.join(a, b): a 경로에 b 폴더 생성 후 경로 반환
    	path: path.join(__dirname, 'dist'),
        filename: 'app.js',
    },
};

4. module.rules.options의 preset 세부설정하기

  • preset 설정 적용 형식: presets: [['preset1', {설정1: 값, 설정2: 값...}], 'preset2']
  • 특히 @babel/preset-env는 설정 중요: preset-env는 최신 코드를 각 브라우저에서 지원하는 옛날 문법에 맞게 바꿔주는 패키지. 지원할 브라우저만 따로 적어주면 webpack 빌드 시 자원을 많이 아낄 수 있다.
  • 브라우저 리스트 키워드 보기: browserslist
// webpack.config.js
module: {
    rules: [{ 
        // 정규표현식 : js, jsx 파일에 룰 적용
        test: /\.jsx?$/, loader: 'babel-loader',
        options: {
            presets: [ 
                ['@babel/preset-env', {
                    targets: {
                        // 한국에서 점유율 5% 이상인 브라우저 전부 지원
                        browsers: [ '> 5% in KR'],
                    },
                    debug: true, // 개발 시 디버그설정
                }], 
                '@babel/preset-react'],
            plugins: [],
        },           
    }],
},
  • @babel/preset-env 설정 후 webpack 실행 결과
...
@babel/preset-env: `DEBUG` option

Using targets:
{
  "chrome": "97",
  "edge": "98",
  "ios": "15.2",
  "samsung": "16"
}
...

5. plugins 설정하기

  • 영상과 다르게 코드 수정된 부분 있음: webpack.Loader~ 대신 npm loader 모듈 직접 불러와서 사용
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
...
plugins : [
    // 모든 loader.options에 debug: true 코드 삽입
    new LoaderOptionsPlugin ({ debug : true })
],
output: { // app.js
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
},
profile
문서화를 좋아하는 개발자

0개의 댓글