본문 바로가기

시리즈/돌아가보기

처음으로 돌아가기 | 웹팩 개발 환경 설정

반응형

 

https://webpack.kr/guides/development/ 오늘 참고하는 공식 문서 링크입니다.

 

 

이전 포스트 | Output 다루기

 

처음으로 돌아가기 | 번들 파일의 종착지, Output 관리하기

https://webpack.kr/guides/output-management/ 해당 문서를 참고하여 작성됩니다. 제가 이해 한대로  작성하는 부분이 많기 때문에, 정석대로 가실거라면 공식문서를 참고해보세요. 이전 포스트 | 애샛 설

duklook.tistory.com

 

 

들어가는 말

웹팩는 번들러 이지만, 개발 환경에서 웹팩을 보다 쉽게 활용할 수 있는 몇 가지 기능들을 지원합니다. 보통 번들러를 통해서 하나의 소스파일로 합쳐지는 경우, 에러가 발생한다면, 각 파일별로 구분하여 알려주는 것이 아니라 하나의 소스파일을 기준으로 로그가 발생하기 때문에, 디버깅하는 것이 어려운 문제로 다가올 수 있습니다.

 

또한, 변경 사항이 발생하는 경우 일일이 컴파일을 시도하면서 변경사항을 추적하는 것도 매우 귀찮은 일이죠. 따라서 웹팩에서는 이러한 문제들을 개선하고 개발자 경험을 향상 시킬 수 있는 다양한 옵션을 지원해주는데 오늘은 이에 대해서 알아보는 시간을 가져볼까 합니다.

참고로 실제 개발과 배포에서 환경 설정은 서로 다릅니다. 이번에 알아보는 옵션들은 개발 환경에서만 사용되는 것이므로 실제 배포환경에서는 webpack 구성을 별도로 가져가야 함을 명심하고 사용하셔야 합니다.

 

 

개발 모드로 변경

우선 실습에 앞서 webpack.config.js 파일로 가셔서 mode를 development 로 변경해주는 작업을 해주어야 한다. 아래에 보면 mode 부분의 옵션이 추가된 것을 볼 수 있습니다. 이렇게 설정해두면, 웹팩이 실행되는 경우 개발 환경을 기준으로 번들링이 시도됩니다.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  // mode 를 추가해줍니다.
  mode:'development',
  entry: {
    index:'./src/index.js',
    add:'./src/add.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title:'아웃풋 관리'
    })
  ],
  output: {
    // filename: 'main.js',
    filename:'[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean:true
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
     {
       test: /\.(csv|tsv)$/i,
       use: ['csv-loader'],
     },
     {
       test: /\.xml$/i,
       use: ['xml-loader'],
     },
    ],
  },
};

 

 

소스맵 설정하기

소스맵은 의역하자면 자원지도 라고 볼 수 있습니다. 앞서 a.js, b,js 와 같이 각각의 모듈들을 번들링을 통해서 c.js 라는 하나의 소트파일로 병합합니다. 이 때 에러가 발생한다면, 로그를 각 모듈 파일로 구분하여 알려주는 것이 아니라 번들링된 c.js 57.32 이런 형식으로 단일 파일의 특정 코드라인을 알려주는 방식이기 때문에, 디버깅하는 것이 어려운 문제에 직면할 수 있습니다(사실 병합된 소스파일이라도 명확한 지점을 알려주기 때문에 크게 불편할 것은 없긴 합니다).

 

개발모드에서는 이러한 불편함을 개선해서 번들링 이전에 소스파일을 기준으로 에러 로그가 발생한 지점을 알려줍니다. 즉, b.js 라는 원본 소스파일에서 발생한 로그는 b.js 12.33 이런 형식으로 해당 파일의 코드라인 정보를 제공해주는 것입니다.

 

아래와 같이 devtool 속성의 값으로 inline-source-map 을 추가해주면 됩니다.

module.exports = {
  // entry: './src/index.js',
  mode:'development',
  entry: {
    index:'./src/index.js',
    add:'./src/add.js'
  },
  devtool: 'inline-source-map',
  plugins: [
    new HtmlWebpackPlugin({
      title:'아웃풋 관리'
    })
  ],
  // ...
  }

 

에러 발생 시키기

그럼 제대로 적용이 되었는지, 실제 확인해보겠습니다.  add.js 파일로 들어가서 존재하지 않는 변수명을 입력해봅니다.

// src/add.js
export default function add(a,b){
    conso
    return a+b
}

 

그리고 add 함수를 index.js 파일에서 import 하여 app 함수 내에서 호출해줍니다.

import './index.css'
import add from './add.js'

function app() {
    const el = document.createElement('div')
    el.textContent = `5와 3을 더하면? ${add(5, 3)}`

    return el
}

(function (app) {
    const root = document.createElement('div')
    root.setAttribute('id', 'root')
    root.appendChild(app())
    document.body.appendChild(root)
})(app)

 

 

이제 npm run build 를 입력하여 실행해보겠습니다. 그 후 브라우저에서 dist 경로의 index.html 파일을 열어줍니다. 그 후 브라우저 개발자 도구를 열어서 콘솔을 확인해보면, add.js 라는 파일에 발생한 오류임을 바로 알 수 있습니다.

 

웹팩 개발 서버 설정

이번에는 웹팩 환경에서 변경사항이 발생하면 메모리 상에서 변경사항을 반영한 번들링을 시도해주는 개발 서버를 설정하는 법에 대해서 알아보겠습니다. 

 

패키지 설치하기

우선 개발서버 패키지를 설치해줍니다. 이 때 개발 환경에서만 사용되므로 개발 의존성에 설치될 수 있도록 해줘야 합니다.

npm install --save-dev webpack-dev-server

 

webpack.config.js 에 옵션 추가

앞서 설치된 모듈을 웹팩에 반영해주도록 하겠습니다. devServer 와 optimization 부분이 추가된 것을 볼 수 있습니다.

optimization 이 추가된 이유에 대해서 알고자 한다면 (https://webpack.kr/guides/development/#using-webpack-dev-server,
https://bundlers.tooling.report/code-splitting/multi-entry/
) 을 읽어보시면 됩니다. 진입점이 여러 개일 때 단일 인스턴스화 되어야 하지만, 인스턴스화가 여러 개 생성되는 경우 문제가 발생할 수 있음을 알려주는 글입니다.

 

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  // entry: './src/index.js',
  mode:'development',
  entry: {
    index:'./src/index.js',
    add:'./src/add.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      title:'아웃풋 관리'
    })
  ],
  output: {
    // filename: 'main.js',
    filename:'[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean:true
  },
  // 서버 옵션을 추가합니다. static 은 번들링된 정적파일의 경로를 설정합니다.
  devServer: {
    static: './dist',
  },
  // index.html 을 기준으로 여러 모듈 파일이 종속되어 있다면 추가해주어야 합니다.
  optimization: {
    runtimeChunk: 'single',
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
     {
       test: /\.(csv|tsv)$/i,
       use: ['csv-loader'],
     },
     {
       test: /\.xml$/i,
       use: ['xml-loader'],
     },
    ],
  },
};

 

 

여기서 알고 가셔야 하는 부분은 해당 개발 서버를 실행하여 변경사항이 반영되는 것 처럼 보이지만, 실제로는 번들링 결과에 영향을 주지는 않습니다. 이는 메모리 상에서 임시적으로 발생하는 것일뿐 개발 서버를 종료하면 메모리 상에 존재하는 변경사항은 초기화됩니다.

 

package.json 스크립트 추가 및 실행 그리고 제한점

이제 개발 서버를 실행하기 위해 스크립트를 추가해줍니다. 여기서 스크립트 속성에  "start" 부분이 추가된 것을 확인할 수 있습니다.

{
  "name": "d3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack serve --open"
  },
  "private": true,
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "css-loader": "^7.1.2",
    "csv-loader": "^3.0.5",
    "html-webpack-plugin": "^5.6.0",
    "style-loader": "^4.0.0",
    "webpack": "^5.92.1",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^5.0.4",
    "xml-loader": "^1.2.1"
  }
}

 

 

실행 이후 아래 문구가 브라우저 개발자 콘솔에 보인다면 성공입니다.

 

이제 파일을 한 번 변경해보겠습니다. 현재 index.html 파일은 하얀 백지 상태입니다. 여기서 css 파일을 변경하여 배경색을 #333 으로 수정해보겠습니다.

하얀 배경

 

 

아래의 노란색 줄 표시부분과 같이 index.css 파일을 변경해줍니다.

 

 

변경 사항이 새로고침 후 반영되는 것을 볼 수 있습니다.

body 의 background: #333

 

변경사항이 바로 반영되게 하려면?  HMR

다만 이대로만 설정하면, 변경사항이 바로 반영되는 것은 아닙니다. 즉, 변경된 파일을 저장하고, 브라우저를 직접 새로고침해주어야 반영이 되는데요. 변경된 사항을 즉시 반영하도록 하려면 Hot Module Replacement 옵션을 활성화 시켜줘야 합니다.

 

HMR 은 웹팩 개발 서버의 내장 플로그인으로 설치되어 있기 때문에, devSserver 의 hot 속성에 true 를 입력하면 됩니다. HMR 설정에 대한 자세한 내용은 (https://webpack.kr/guides/hot-module-replacement) 여기서 확인 바랍니다.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  // entry: './src/index.js',
  mode:'development',
  entry: {
    index:'./src/index.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      title:'아웃풋 관리'
    })
  ],
  output: {
    // filename: 'main.js',
    filename:'[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    clean:true
  },
  // 서버 옵션을 추가합니다. static 은 번들링된 정적파일의 경로를 설정합니다.
  devServer: {
    static: './dist',
    hot: true,
  },
  // index.html 을 기준으로 여러 모듈 파일이 종속되어 있다면 추가해주어야 합니다.
  optimization: {
    runtimeChunk: 'single',
  },
  module: {
    rules: [
      {
        test: /\.css$/i,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(png|svg|jpg|jpeg|gif)$/i,
        type: 'asset/resource',
      },
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/i,
        type: 'asset/resource',
      },
     {
       test: /\.(csv|tsv)$/i,
       use: ['csv-loader'],
     },
     {
       test: /\.xml$/i,
       use: ['xml-loader'],
     },
    ],
  },
};

 

 

적용 이후 어떻게 달라졌는지 영상으로 확인해 봅시다.

 

 

웹팩 미들웨어 설정

미들웨어 부분은 다루지 않을 겁니다. 이 부분은 공식 문서 ( https://webpack.kr/guides/development/#using-webpack-dev-middleware) 를 참고하시면 좋을 것 같습니다.

 

 

나가는 말

오늘은 웹팩을 개발환경에서 다루는 방법에 대해서 알아보았습니다. 사실 위에서 튜토리얼은 일부 예시에 불과할 뿐 설정할 수 있는 옵션은 방대합니다. 이는 각자의 상황에 맞게 찾아서 사용하면 되는 부분이라 공식문서에서도 깊이 다루고 있지는 않습니다. 말 그대로 가져다가 적용만 하면 되는 일이니까요.

 

다음 시간에는 코드 스플릿이라는 기법을 웹팩에서 어떻게 적용하는지에 대해서 정리해보는 시간을 가져볼 것입니다. 고생하셨습니다.

반응형