React

#5 Webpack

Sila 2022. 4. 22. 20:07

Webpack에 대해 알아보자.

 

파일, 코드의 양이 많아지면서 개발자들은 코드들을 분리해 (모듈화) 다른 파일에 나누고,

 

import, require 등을 통해 다른 파일의 데이터를 가져오는 식으로 작업을 능률화해왔다.

 

이를 한 단계 더 발전시킨 것이 webpack이다.

 

webpack은 이런 파편화된 데이터들을 통합하는 것을 도와준다.

 

이는 기본적으로 nodeJS 환경에서 돌아가기 때문에 npm을 이용해 간단하게 설치할 수 있다.

 

일단 간단한 js 파일을 만들고 react, webpack을 어떤 식으로 사용할 수 있는지에 대해 간단한 예제를 들어 알아보자.

 

작업을 진행할 폴더를 하나 만든다. (여기서는 practice라고 명명)

 

npm init -y
npm i react react-dom
npm i -D webpack webpack-cli

 

-D flag는 development dependeny라는 의미로, 개발할때 사용할 라이브러리를 의미한다.

 

'개발용'이므로 이는 배포될 때 포함되지 않는다.

 

이제 현재 폴더 내에 각각 dist, public, src라는 이름을 가진 폴더 총 3개를 만든다.

 

public에는 html 파일을, src에는 js 파일을, 그리고 dist에는 webpack으로 이를 통합해준

 

js 파일이 나중에 생성될 것이다.

 

우선 public에 다음과 같이 index.html 파일을 만들자.

 

<!--  practice/public/index.html  -->

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./dist/style.css">
</head>
<body>
    <div id="root"></div>
    <script type="text/javascript" src="./dist/bundle.js">

    </script>
</body>
</html>

 

이제 우리가 jsx 파일을 생성한 후, 이를 webpack으로 묶어 bundle.js라는 파일이 생성되면

 

브라우저는 이 html에서 그걸 불러올 것이다.

 

이제 src폴더에서 assets, component 2개의 폴더를 생성한다.

 

전자에는 css, 후자에는 jsx 파일들이 보관될 것이다.

 

src 폴더 바로 하위에 index.jsx 파일을 생성해주자.

 

이 안에 모든 컴포넌트를 통합한 컴포넌트를 렌더링하는 코드를 넣을 것이다.

 

// practice/src/index.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'

const container document.querySelector('#root')
const root = ReactDOM.createRoot(container)
root.render(<App/>

 

 

이제 practice폴더에서 webpack.config.js를 생성한 후, 다음과 같이 작성해준다.

 

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

module.exports = {

    name:'react-project',
    mode:'development',
    devtool:'eval',

    // resolve, entry, module, plugin, otput의 의미를 알아야하낟.

    // resolve : 확장자나 파일 제거
    resolve : {
        extensions : ['.js', '.jsx', '.css']
    },

    // entry : 앞으로 번들할 파일들
    entry: {
        app:['./src/index.jsx']
        // 이 파일 기준으로 require 한 애들 다 가져옴 가져온 파일의 그것도 다 가져옴
    },

    module: {
        rules:[{
            // 번들할 파일 중 확장자
            test:/\.jsx?/,
            loader: 'babel-loader', // webpack, babel을 연결해주는 babel 라이브러리
            options: {
                presets : [
                    ['@babel/preset-env', { // 예전 버전 브라우저에서도 돌아가게 해주는..
                        targets: {
                            browsers:['last 2 chrome versions', '> 5% in KR'] 
                            // 구글에 browserslist 검색 > github에 있다.. md로 설명도 나와있음..
                        },
                        debug:true // 조건에 맞는 브라우저 출력 > 안되는걸 되는걸로 바꾼다..
                    }],
                    '@babel/preset-react' // jsx를 사용하기 위해..
                ],
                plugins: [
                    'react-refresh/babel'
                ]
                // 이 플러그인은 바벨에 대한 플러그인 (새로고침 없이 바벨이 바로 수정되게)
            }
        }, {
            test:/\.css$/,
            use:[MiniCssExtractPlugin.loader, 'css-loader']
        }] // rules[0] 은 babel, rulse[1]은 css에 관한 내용
        // 다른것도 넣고 싶으면 또 배열에 3번쨰 element 추가하면 됨
    },
    // 이 플러그인은 전체에 대한 플러그인 
    plugins : [
        new webpackPlugin(),
        new HtmlWebpackPlugin(),
        new MiniCssExtractPlugin({filename:'style.css'}) // 파일을 만들어주는..
    ], 


    // output: 내보낼 파일의 위치, 파일명
    output: {
        path: path.join(__dirname, 'dist'),
        filename: 'bundle.js',
        publicPath:'/dist'
    },

    devServer: {
        static: {
            directory: path.join(__dirname, 'public')
        },
        compress:true,
        port:3000,
        hot:true, // means hotload
        historyApiFallback:true // about reload
    },

}

 

일일히 뭐가 어떤 역할을 하는지 설명하긴 힘들어 주석에 필요한 설명을 달아두었다.

 

요약하자면

 

1. 처음 인식을 시작할 파일 (이 파일을 기준으로 import, require 한 파일들을 전부 읽어줌)

 

2. 인식할 수 있는 확장자

 

3. babel 인식

 

4. 작성한 코드가 돌아갈 수 있는 브라우저 설정

 

5. 데이터 갱신을 인지해 바로 새로고침 하는 플러그인 추가 (nodemon 등을 생각해보면 된다.)

 

6. 작성된 파일을 묶어 새로운 파일을 생성했을 때, 그 파일이 생성될 위치, 로딩할 서버 port

 

등을 설정해준 것이다.

 

라이브러리들도 다음과 같이 전부 설치해주면 된다.

npm i -D babel-loader @babel/preset-env @babel/preset-react

 

바벨등에 대한 라이브러리이다. webpack과 babel을 통역해주는 역할을 한다고 보면 된다.

 

npm i -D webpack-dev-server

 

서버를 통해 돌아갈 수 있도록 해주는 (port를 차지할 수 있는) 라이브러리

 

npm i -D html-webpack-plugin @pmmmwh/react-refresh-webpack-plugin react-refresh

 

파일 갱신 시 새로고침없이 바로 브라우저에서 새로 렌더링해주는 플러그인 3개

 

npm i -D mini-css-extract-plugin css-loader

 

react에서 html element를 형성할 때 style attribute와 style element를 인식할 수 있게 해주는 라이브러리

 

여기까지 하면 우선 기본적인 세팅은 끝났다.

 

이제 src 폴더 바로 하위에 App.jsx파일을 만들고, 이를 index.jsx에서 통합하자.

 

// practice/src/App.jsx

import React, { Component } from 'react'

class App extends Component {
   state = {
      value:'hello'
   }
   
   render() {
      return (
         <>
            {this.state.value}
         </>
      )
   }
}

export default App

 

작성이 완료되었으면 이제 package.json 파일을 열어보자.

 

완성된 파일을 서버에서 돌리려면 여기서 수정을 가해야 한다.

 

scripts 부분에 다음과 같이 추가하자.

 

"scripts" : {
	// 중략
    "webpack":"webpack",
    "dev":"webpack server --env development"
    // 두 줄을 추가
}

 

이제 터미널에 webpack을 입력하면 html, js,jsx 파일을 통합해 새로운 js파일을 만들어 줄 것이다.

 

이 통합된 파일은 아까 지정한 경로에 생성된다. (여기서는 /practice/dist/bundle.js)

 

마지막으로 터미널에 npm run dev를 입력 후, localhost:3000으로 접속해보자.

 

hello가 잘 나온다면 value값을 수정하고 저장해보자. 바로 렌더링이 갱신될 것이다.

 

다음 글에서는 여기에 이어서 react로 생성된 element들을 스타일링하는 여러 방법에 대해 알아보자.

'React' 카테고리의 다른 글

#7 곱셈 프로그램 만들기  (0) 2022.04.24
#6 Styling  (0) 2022.04.22
#4 tictectoe 게임 만들기  (0) 2022.04.17
React #3 Class Component - data 변화 인식  (0) 2022.04.13
React #2 Class Component  (0) 2022.04.13