Webpack

JavaScript

Webpack

  • html은 하나의 JavaScript 파일만 불러올 수 있는데 Webpack을 사용하면 자바스크립트, css, 이미지 등을 하나의 파일로 묶어서 내보낼 수 있다
  • 자바스크립트, css, 이미지 등을 모듈이라고 부르며 Webpack은 이들을 묶는 모듈 번들러 (Module Bundler)이다

설치

  • webpack - 모듈 번들러
  • webpack-cli - 웹팩의 커맨드 라인 인터페이스
npm i -D webpack
npm i -D webpack-cli

실행

실행시 webpack이라고 적으면 명령어로 등록이 안되어있으므로 인식할 수 있게 해줘야 한다

    1. 명령어로 등록 한다
    1. scripts에 적어주고 npm run [script 명령어] 로 실행한다
    2. npm run dev로 실행

      //package.json
      "scripts": {
      "dev": "webpack",
      }
    1. npx webpack 으로 실행

webpack.config.js

  • webpack.config.js가 변경되면 새로고침이 필수

zerocho 블로그 참고 zerocho 유투브 react 웹게임 참고 webpack 공식문서

mode

  • 개발용은 development 배포용(실서비스용)은 production (배포용은 자동으로 최적화가 적용되어 최적화 플러그인들이 많이 호환되지 않음)

    devtool

  • 개발시엔 'eval', 배포용은 'hidden-source-map'을 많이 쓴다고 한다
  • 'eval'은 빠르고 'hidden-source-map'은 소스 숨기기
devtool: 'eval',

resovle

  • 확장자는 entry에 js, jsx, css, json 등 여러가지를 입력할 수 있는데 다 적기 귀찮다면 resolve에 entry 확장자들을 적어주어 자동으로 인식하게 하면 된다
resolve: {
  inextensions: ['.js', '.jsx'],
},
entry: {
  index: ['./a', './c'],
},

entry - 입력

  • 웹팩이 파일을 읽어들이기 시작하는 파일 경로로 이 entry를 통해 모듈들을 로딩하고 하나의 파일로 묶는다
  • entry의 키가 index.js면 index.js로 통합된다
entry: {
  index: '파일 경로',
}
  • entry의 키를 여러개 넣으면 여러 JS 파일로 결과물이 만들어진다. 보통 멀티페이지 웹사이트에서 사용한다고 한다
entry: {
  index: ['./a.js', './b.js'],
}
  • 만약 a.js에서 이미 b.js를 불러오고 있다면 b.js를 적을 필요가 없다
entry: {
  index: ['./a.js'],
}

module

적용할 모듈을 명시

  • test: /\.jsx?/ - js와 jsx에 적용한다
  • loader - 적용할 rule
  • options - rule의 옵션

    • presets와 plugins는 아래 예시처럼 나눠서 작성
module: {
  rules: [{
    test: /\.jsx?$/,
    loader: 'babel-loader',
    options: {
      presets: [
        '@babel/preset-env', 
        '@babel/preset-react'
      ],
      plugins: ['@babel/plugin-proposal-class-properties'],
    }
  }],
}
  • preset-env에 대한 옵션을 설정하고 싶다면 preset을 배열로 감싸고 클래스를 항목으로 추가해 옵션을 설정한다

module: {
	...
  
    options: {
      presets: [
        ['@babel/preset-env', {
          targets: {
            browsers: ['> 5% in KR', 'last 2 chrome versions'],
          },
          debug: true,
        }],
         '@babel/preset-react'
        ],
      ...
    }

plugins

웹팩의 확장 프로그램 (결과물의 형태를 변형)

  • 실무에서 몇 가지 사용된다
  • 아래 예시는 로더들에 모두 debug: true 옵션을 추가하는 기능
plugins: [
  new webpack.LoaderOptionsPlugin({debug: true}),
],

output - 출력

entry로 찾은 모듈을 하나로 묶은 결과물을 반환하는 위치

  • 만약 현재 폴더 안에 dist가 있고 거기에 출력을 하려한다면현재 폴더와 그 안에 들어있는 dist를 합치도록 하면 된다
output: {
  path: path.join(__dirname, 'dist'),
  filename: 'index.js',
},
//webpack.congif.js
const path = require('path');
const webpack = require('webpack');

module.exports = {
  mode: 'development'
  resolve: {
  	extensions: ['jsx', 'js'],
  }, 
  entry: {
    index: './pages/index',
  }
  module: {
    rules: [{
      test: /\.jsx?$/,
      loader: 'babel-loader',
      options: {
        presets: [
          ['@babel/preset-env', {
              targets: {
                browsers: ['> 1% in KR'],
              },
              debug: true,
          }],
          '@babel/preset-react'
        ],
        plugins: [],
      }
    }],
  },
  output: {
    path: path.resolve(__dirname, 'dist/js'),
    filename: 'index.js'
  },
  devtool: 'eval',
};

hot loader && webpack-dev-server

zerocho 유투브 참고

  • hot loader 에서 react-refresh로 바뀌었다
  • react가 원래 reloading은 해준다 (변경되면 새로고침)

    • hot reloading은 기존 데이터를 유지하면서 새로고침을 해준다는 것이 주요 특징

설치

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

명령어

npm run dev 로 실행

//package.json
"scripts": {
  "dev": "webpack server --env development"
}

webpack.config.js

  • react-refresh 플러그인을 불러와서 plugins에 설정
  • module의 plugins에 react-refresh 명시
  • devServer에 output의 publicPath를 넣고 hot: true로 설정
//webpack.config.js

const RefreshWebpackPlugin = requir('@pmmmwh/react-refresh-webpack-plugin');

...

module: {
  rules: [{
    ...
    options: {
      presets: [
        ...
      ],
      plugins: [
		'react-refresh/babel',
      ],
    }
  }],
},


plugins: [
  new RefreshWebpackPlugin()
],
output: {
  path: path.resolve(__dirname, 'dist/js'),
  filename: 'index.js'
  publicPath: '/dist/',
},
devServer: {
  publicPath: '/dist/',
  hot: true,
},
예전 webpack-dev-server와 hot loader 설명 (&& publicPath vs path 설명)
  • webpack-dev-server - 수정사항이 발견됐을 때 자동으로 프로그램을 재실행해주고 개발 서버를 제공하는 기능 (webpack.config.js를 읽어서 빌드하고 항상 서버로 유지시킨다 localhost:8080)
  • react-hot-loader - 수정사항을 감지하는 기능
//webpack.config.js
plugins: [
  'react-hot-loader/babel',
]
  • webpack-dev-server를 사용할 때는 dist/index.js처럼 경로를 쓰지 않고 바로 파일명만 명시해야한다

    • path: 실제 경로
    • publicPath: 가상의 경로 (NodeJS의 express.static과 유사)
<!-- index.html-->
<script src='./index.js'></script>
  • 스크립트 경로를 바꿔도 된다
//webpack.config.js
output: {
  ...
  publicPath: '/dist/',
}
<!-- index.html-->
<script src='./dist/index.js'></script>
  • webpack.config.js가 변경되면 새로고침이 필수