React

[Webpack] creat-react-app 없이 react 시작하기

Alexim 2022. 6. 14. 20:45

웹팩은 js, jsx, css 등 파일들을 모아 하나의 JS파일로 만들어준다.

creat-react-app 으로 react 프로젝트를 시작하게 되면 따로 자동으로 webpack 환경 셋팅이 된다.

리액트에서 컴포넌트가 담긴 파일(js, jsx....)들을 모아 하나의 파일처럼 사용할 수 있는 이유가 webpack에 있다.


📗 Webpack Entry, Output

Webpack에서 제일 중요한 2가지가 바로 Entry와 Output이다.

 

Entry point

- 모든 의존 객체들이 모인 웹팩의 시작점을 정의한다.

 

Output

- 빌드 과정에서 어느 곳에 js파일과 정적 파일들을 모을지 정의한다.


📗 creat-react-app 하지 않고 react 시작하기

 

1. root 폴더에서 npm init  (package.json 생긴다)

2. npm i react react-dom (react, react-dom 설치)

3. npm install --save-dev webpack webpack-cli

//package.json파일

"dependencies": {
    "react": "^18.1.0",
    "react-dom": "^18.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.18.5",
    "@babel/preset-env": "^7.18.2",
    "@babel/preset-react": "^7.17.12",
    "babel-loader": "^8.2.5",
    "webpack": "^5.73.0",
    "webpack-cli": "^4.10.0"
  }

(devDependencies : 개발용으로만 사용한다는 의미 npm install --save-dev 또는 npm i -D 하게되면 dev용으로 설치된다.) 

4. index.html

<body>
  <div id="root"></div>
  <script src="./dist/app.js"></script>
</body>

5. root폴더에 client.jsx , WordRelay.jsx 만들기

// client.jsx 파일
// const React = require("react");
// const ReactDom = require("react-dom");

import React from "react";
import ReactDom from "react-dom";

// const WordRelay = require("./WordRelay");
import WordRelay from "./WordRelay";

ReactDom.createRoot(document.querySelector('#root')).render(
  <WordRelay />
)

node의 module 시스템인 require로 가져와도 되고 ES6의 모듈 시스템인 import로 가져와도 된다.

// WordRelay.jsx 파일
// const React = require("react");
import React from "react";
const { Component } = React;

class WordRelay extends Component {
  render() {
    return (
      <div>hi</div>
    )
  }
}

// module.exports = WordRelay;
export default WordRelay;

require로 불러왔을 때는 module.exports로 내보내기

 

6. dist 폴더 만들기

 


babel 설치하기

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

 

7. root 폴더에 webpack.config.js 만들기 

const path = require('path'); //node에 기본으로 들어있음

module.exports = {
  name: 'wordrelay-setting',
  mode: 'development', //실서비스는 production
  devtool: 'eval',
  resolve: {
    extensions: ['.js', '.jsx'],
  },

  entry: {//입력
    app: ['./client'],
    //client.jsx에서 WordRelay를 불러오고 있기 때문에 WordRelay는 안적어줘도 된다.
    //그리고 위에 resolve extension 넣으면 확장자도 안넣어도 됨
  },

  module: {
    rules: [{
      test: /\.jsx?/,
      loader: 'babel-loader',
      options: {
        presets: [
          '@babel/preset-env',
          '@babel/preset-react'
        ],
      }
    }],
  },

  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
  }, //출력
};

- entry

entry는 위에서 본 것처럼 모든 의존 객체들을 app에 적어주면 되는데 client.jsx에서는 지금 WordRelay를 import해서 불러와줬으므로 안적어줘도 된다. Webpack에서 그런 것들까지 다 가져올 수 있다. 위 resolve에서 extensions에 확장자를 등록해주면 entry.app에서 확장자를 적어주지 않아도 된다.

 

- output

맨위 const path는 node에 기본적으로 들어있는 기능으로 path를 등록할 수 있다. 

path.join을 하면 현재 폴더 주소를 자동으로 만들어준다. c://folder//folder//..... 이렇게 길게 입력하지 않아도 되게 만들어줌

filename인 app.js로 출력된다.

 

- module

entry의 파일을 읽고 module을 적용한다.

loader를 적용하는데 loader의 option으로 밑에 preset을 적어준다.

 

8. webpack 실행하기

 // package.json 
 
 "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack"
  },

dev: webpack 등록해주고

npm run dev

하면 root 폴더 안 dist폴더에 app.js가 생성된다.

 


📗 webpack 자동 빌드 - react refresh

1. react refreash 설치

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

 

2. 서버 만들기

npm i -D webpack-dev-server

 

package.json

 "scripts": {
    "dev": "webpack serve --env development"
  },

webpack.config.js

const path = require('path');
const { webpack } = require('webpack');
const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');

module.exports = {
  mode: 'development',
  devtool: 'eval', // hidden-source-map,
  resolve: {
    extensions: ['.jsx', '.js'],
  },

  entry: {
    app: './client',
  },
  module: {
    rules: [{
      test: /\.jsx?$/,
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', {
            targets: {
              browsers: ['> 5% in KR']
            },
          }],
          '@babel/preset-react',
        ],
        plugins: [
          '@babel/plugin-proposal-class-properties',
          'react-refresh/babel',
        ]
      }
    }],
  },
  plugins: [
    new RefreshWebpackPlugin()
  ],

  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'app.js',
    publicPath: '/dist',
  },
  devServer: {
    // publicPath: '/dist', //여기에 저장
    hot: true, //변경점 감지해서 publicPath 업데이트 해줌
    devMiddleware: { publicPath: '/dist/' },
    static: { directory: path.resolve(__dirname) },  
  },
  • const RefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
  • 'react-refresh/babel',
  • devServer

 

 

 

출처 및 참고

1. 제로초님 웹게임으로 배우는 리액트 강좌

2. https://serzhul.io/JavaScript/learn-webpack-in-under-10minutes/