프론트엔드 환경 구축

Node.js 환경에서 ESLint, Webpack, Webpack-dev-server의 HMR을 이용해서 개발하기

출처
webpack 개발환경구축1
webpack 개발환경구축2
webpack 빌드환경 구축1
webpack 빌드환경 구축2
프론트엔드 개발자를 위한 토막상식 by 박성범
babel과 webpack을 이용한 es6 환경구축
프론트엔드 개발환경의 이해 by 김정환

Directory Tree

\
\node_modules       // 노드 모듈
\src                // 개발중인 js 파일 이미지 등이 저장될 곳
    index.js        // 메인 javascript 파일
\static             // 정적 HTML에서 사용할 자료(assets)들이 저장될 위치
index.html          // 웹엡의 메인 페이지
package.json
webpack.config.js

1. webpack 설치

mkdir webpack-demo && cd webpack-demo
npm init -y
npm install webpack webpack-cli webpack-dev-server --save-dev

webpack
코어 모듈

webpack-cli
커맨드 라인을 통해 웹팩을 제어할 수 있도록 해주는 모듈 사실상 마지막 결과물을 빌드할 때 사용된다.

webpack-dev-server
웹팩을 이용한 빌드 결과물을 Node.js의 웹서버를 이용해 마치 웹 서비스에서 작동되는 것처럼 웹 브라우저에서 접근할 수 있도록 한다. 개발도중 개발 디버깅 등 다양한 개발에 편한 환경을 제공한다. 개발 도중에 사용된다.

2. 프로젝트 파일 생성

<!-- index.html -->
<!doctype html>
<html>
<head>
	<title>Webpack Test Project</title>
</head>
<body>
</body>
</html>
/* src/index.js */
function writecom() {
	let element = document.createElement('div');
	element.innerHTML = 'Hello Webpack';
	return element;
}
document.body.appendChild(writecom());

3. 플러그인 설치

npm install html-webpack-plugin -D

html-webpack-plugin
Webpack으로 생성된 JS 파일을 index.html 파일 같은 HTML 파일에 삽입하는 <script src="index.js"> 형태 태그를 자동으로 만들어 줍니다.
그렇기 때문에 위에 index.html 파일에 JS 파일을 불러오는 <script> 태그가 없었던 것 입니다.

HTML에 한 두줄 추가 하면 되는 걸 html-webpack-plugin을 사용하는 이유는 복잡한 프로젝트를 사용하다 보면 단순히 하나의 JS 파일을 생성하는 것이 아니라 여러개의 JS 파일을 생성해야 합니다.
더구나 그 출력파일은 이름 중복을 피하기 위해서 hash 값을 이름으로 지정하는 경우가 있기 때문에.. 직접 추가하는 태그를 작성하기 불가능합니다.

4. webpack.config.js 파일 생성

Webpack을 사용하기 위해서는 우선 여러가지 설정을 지정할 파일이 있어야 하는데, 기본 설정 파일의 이름은 Webpack.config.js입니다.
프로젝트 root에 이 파일이 있고 webpack 실행시 별도 설정 파일을 지정하지 않으면 이 파일을 기본 설정 파일로 자동으로 인식합니다.

/* webpack.config.js */
"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
 
module.exports = {
  mode: "development",
  entry: {
    app: "./src/index.js"
  },
  devtool: "cheap-module-eval-source-map",
  devServer: {
    contentBase: false,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  output: {
    path: undefined,
    filename: "[name].js"
  }
};

entry
Webpack에서 번들링할 JS 파일을 지정합니다.
번들링할 파일을 여러개 지정할 수 있는데, 여기서는 app 이라는 이름에 index.js를 지정했습니다.
여러개의 JS 파일을 번들링 할 경우 app : 'index.js', print: 'print.js' 이런 형태로 지정할 수 있습니다.
이때 app 이름의 번들링 대상은 index.js, print 이름의 번들링 대상은 print.js 입니다.

plugins
Webpack에서 사용할 플러그인을 지정하고 그 설정합니다.
filename - html-webpack-pluing이 생성할 파일 이름을 지정합니다.
tempate - <script> 태그를 집어 넣을 원본 파일을 지정합니다. 지정이 없으면 기본적 형태로 HTML 파일을 자동으로 생성합니다.
inject - <script> 태그를 삽입할지, 삽입 한다면 어느 태그 아래(<body>|<head>) 집어 넣을지 설정할 수 있는데, 더 자세한 내용이 필요하면 깃허브 페이지를 참조하세요
HotModuleReplacementPluing 은 웹팩에서 번들링한 파일이 수정되면 그 것을 감지해서 즉시 즉시 반영해주는 플러그인입니다.
워낙 유명하고 항상 사용되는 것이다 보니 Webpack자체에 내장 된거 같습니다.
이 플러그인을 사용할 때 별도로 설정할 필요는 없지만, Webpack-dev-server 설정에 'hot: true' 값을 지정해야 합니다.

output path는 번들링 대상이 저장될 경로입니다.
여기서는 undefind 로 지정했는데, 이렇게 되면 webpack은 번들링된 파일을 생성하지 않습니다.
대신에 메모리 상에는 번들링된 파일이 있고 webpack-dev-server는 메모리상에 번들링된 파일로 작동합니다.
Webpack-dev-server를 사용할때는 아직 개발 중일테니 실제 파일을 생성할 필요가 없다고 생각했고 제가 사용하는 Webpack 설정의 기본 컨셉은 빌드 전까지 번들링된 파일을 생성하지 않는 것입니다.
filename은 번들링 되서 생성되는 JS 파일 이름을 지정합니다. 여기서는 [name].js로 되어 있는데, 앞에 entry에서 app 이라는 이름으로 index.js를 지정했기 때문에 번들링 된 파일의 이름은 app.js 입니다.

5. npm script 생성 - package.json 수정

webpack config 파일을 생성했으면 package.json을 수정해서 npm script를 만들도록 합니다.

/* package.json */
{
  "name": "test",
  "version": "1.0.0",
  "description": "Test",
  "license": "MIT",
  "scripts": {
    "dev": "webpack-dev-server"
  },
  "devDependencies": {
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.24.0",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.10"
  }
}

scripts 항목을 수정하고 npm run dev 를 실행합니다.
웹페이지에 localhost:8080 접속하면 웹페이지에 출력 내용을 볼 수 있습니다.
index.html 에 index.js가 삽입되어, 페이지에 Hello world라는 글이 나타난 것이 확인됩니다.
F12버튼을 눌러 개발자 모드를 활성화하여 html 파일의 내용을 보면 직접 입력하지 않은 <script> 태그가 html-webpack-plugin을 통해 생성되었고, 번들링 된 JS 파일의 이름이 app.js 인 것을 확인할 수 있습니다.여기에는 없지만 app.js와 index.js를 클릭해보면 파일 내용을 확인할 수 있습니다.



<- Webpack, Webpack-dev-server를 최소한 돌아 가게 하는 과정


-> Module을 통해 css와 img 파일을 번들링, Static assets 사용을 위해 copy-webpack-plugin을 사용하기



6. 파일 번들링 - Webpack Module 사용

javascript나 css 등등의 파일들을 번들링 하기 위해 각 파일의 loader를 webpack에서 module 형태로 사용해야 합니다.
css 파일을 위해 style-loader와 css-loader를 사용하고, 그 외 파일들을 번들링 하기 위해 url-loader를 사용하겠습니다.
구 버전 웹브라우저 혹은 하위 호환성을 위해 babel 사용 필요성이 있다면 Module 부분에 JS 파일을 babel-loader에서 처리 하도록 해주면 됩니다.

6.1. css-loader 및 style-loader

style-loader, css-loader 설치합니다.

npm i -D style-loader css-loader

css-loader
CSS 파일을 정리(?) 해주는 역활을 합니다. 공식문서에서는 의존성을 해결한다고 되어 있는데요. css도 다른 css 파일을 import 하는 경우가 많이 있는데, 예를 들어 a.css 파일 중 b.css 파일의 내용을 import하는 경우 a.css 만 번들링 한다면 오류가 생기겠죠. 이러한 상황을 b.css에 의존성이 있다고 하는데, 이런 import 내용을 정리해주는 일을 합니다.

style-loader
css 내용을 html style 태그로 정리해주는 역활을 합니다. 그렇기 때문에 css-loader와 style-loader를 동시에 사용합니다. 조금 더 정확하게는 css-loader -> style-loader 로 처리되게 합니다. 만일 sass를 사용 할 경우 처리 순서는 sass-loader -> css-loader -> style-loader 순서입니다. (sass나 Postcss를 사용하시는 분은 다른 문서를 검색해보세요. 전 디자인적 감각이 없어서 거의 안쓰거든요...) sass-loader가 sass를 해석한 다음 css-loader에게 넘겨주면 css-loader는 그 의존석을 해결하고 다시 style-loader에게 넘겨서 html에 <style> 태그로 삽입한다고 합니다.

6.2. url-loader

url-loader를 사용하기 위해서는 file-loader 도 같이 설치해 주어야 합니다.

npm i -D file-loader url-loader

url-loader
file을 Data URI Scheme 형태로 Javascript 파일 안에 저장합니다.
url-loader에서 파일의 크기가 클 경우 Data URI Scheme 형태로 번들링 하는 것이 극히 안좋기 때문에 일정 크기 이상의 파일은 file-loader 를 이용해 복사 하는 형태로 번들링 합니다.
그렇기 때문에 file-loader를 저희가 설정하지 않더라도, 설치하는 것 입니다.

file-loader
file-loader는, Javascript로 import 하는 파일을 복사하는 역활을 합니다. 예를 들어 scr/index.js에서 같은 폴더에 있는 scr/a.png파일을 import 해서 번들링 한 상황을 가정하였을때 번들링 결과물이 저장되는 dist/index.js 에서는 a.png 파일이 없기 때문에 오류가 날 것입니다.

6.3. webpack.config.js 파일 수정

"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const webpack = require("webpack");
 
module.exports = {
  mode: "development",
  entry: {
    app: "./src/index.js"
  },
  devtool: "cheap-module-eval-source-map",
  devServer: {
    contentBase: false,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    new webpack.HotModuleReplacementPlugin()
  ],
  output: {
    path: undefined,
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader:'url-loader',
        options: {
          limit: 10000,
          name: 'static/[name].[hash:7].[ext]'
        }
      }
    ]
  }
};

webpack.config.js 파일에 module 항목을 추가 했습니다.
파일 번들링을 위한 module 설정을 보면, test에 정규 표현식(regex)을 통해 파일을 지정해주면, 그 파일을 처리할 loader를 지정해 주는 방식입니다.
url-loader는 loader 항목으로 지정했는데
style-loader, css-loader는 use 항목으로 지정한 것이 다른 점인데
css 파일을 css-loader -> style-loader 2개의 로더를 거쳐야 하기 때문에 use 항목으로 설정하는 것이라 이해 했습니다.
먼저 처리할 loader를 나중에 써야 한다고 되어 있습니다. css-loader, style-loader 이렇게 작성하면 처리 순서가 반대로 되어서 오류가 난데요. 만일 sass-loader 도 사용한다면 sass-loader를 가장 마지막에 써야겠죠.

6.4. url-loader의 옵션

limit은 Base URI sheme로 저장할 최대 파일 크기를 지정합니다 현재 limit(10kb)보다 파일이 크면 file-loader를 이용하여 단순히 파일을 복사합니다.
name은 저장될 파일 이름을 지정합니다. 저는 static 폴더에 [원본이름].[파일해쉬 중 처음 7자리].[확장자] 이렇게 저장했습니다.

6.5. index.js 수정

테스트를 위해 그림파일을 삽입해봅니다.
로고 파일을 src 폴더에 넣고 index.js 다음과 같이 수정합니다.

/* src/index.js */
import Logo from './logo.png'
function writecom(){
    let element = document.createElement('div');
    element.innerHTML = 'Hello Webpack';

    let myLogo = new Image();
    myLogo.src = Logo;

    element.appendChild(myLogo);
    
    return element;
}
document.body.appendChild(writecom());

6.6. 번들링 테스트

npm run dev

7. Static Asset 사용 copy-webpack-plugin

\
\node_modules       // 노드 모듈
\src                // 개발중인 js 파일 이미지 등이 저장될 곳
    index.js        // 메인 javascript 파일
\static             // 정적 HTML에서 사용할 자료(assets)들이 저장될 위치
    .png, .css
index.html          // 웹엡의 메인 페이지
package.json
webpack.config.js

static 폴더에 각종 파일을 넣어 이대로 빌딩하면 static 폴더의 내용을 webpack이 읽지 못하기 때문에
static 폴더의 내용을 그대로 복사해서 webpack에 넣어주거나,
빌딩 결과 폴더에 넣어줄 플로그인을 사용해야하는데, 그 플러그인이 copy-webpack-plugin 입니다.

7.1. index.html에 Static Asset 추가

static폴더에 img.png 파일을 넣습니다.
index.html파일을 다음과 같이 수정합니다.

<!doctype html>
<html>
<head>
    <title>Webpack Test Project</title>
</head>
<body>
        <img src="static/img.png">
</body>
</html>
npm run dev

img.png를 읽어 오지 못한 것을 확인합니다.
webpack-dev-server는 메모리에 저장된 번들링 파일을 읽어서 웹페이지를 나타낸다고 했는데,
static 폴더의 내용은 webpack에서 읽은 적이 없기 때문에 현재 웹 브라우저에서 파일이 없다고 나타나는 것입니다.
그렇다고 static 폴더의 내용을 loader로 따로 번들링하기는 복잡하고 단순히 복사만 하면 되기 때문에 copy-webpack-plugin을 사용합니다.

7.2. copy-webpack-plugin 설치 및 설정

npm i -D copy-webpack-plugin

webpack.config.js 에서 copy-webpack-plugin을 설정합니다.
상단에 아래 내용 추가

const CopyWebpackPlugin = require('copy-webpack-plugin')

플러그인 항목에 copy-webpaack-plugin을 추가합니다.

plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    new webpack.HotModuleReplacementPlugin(),
    new CopyWebpackPlugin([
      {
        from: 'static',
        to: 'static'
      }
    ])
  ],

from: 에 지정된 폴더의 파일들을 to: 위치로 복사하도록 설정합니다.

npm run dev

8. 빌드 환경 구성

8.1. 빌드 환경을 위한 webpack.prod.js 파일 생성

Webpack.config.js 파일을 그대로 복사한 다음, 개발을 위한 webpack-dev-server라던지 기타 설정 부분을 제외하고, 빌드 결과물이 출력 될 폴더를 지정합니다.

/* webpack.prod.js */

"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
/* 삭제 const webpack = require("webpack"); */
 
module.exports = {
  mode: "development",
  entry: {
    app: "./src/index.js"
  },
  /* 삭제 devtool: "cheap-module-eval-source-map", */
  /* 삭제 devServer: {
    contentBase: false,
    hot: true
  }, */
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    /* 삭제 new webpack.HotModuleReplacementPlugin(), */
    new CopyWebpackPlugin([
        {
          from: 'static',
          to: 'static'
        }
      ])
  ],
  output: {
    path: path.resolve(__dirname, "dist"), /* 변경 undefined, */
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader:'url-loader',
        options: {
          limit: 10000,
          name: 'static/[name].[hash:7].[ext]'
        }
      }
    ]
  }
};

빌드 환경에서는 HMR을 사용하지 않아 삭제합니다.
devtool은 브라우저 디버깅을 위해 devtool(브라우저 개발 도구)에 source-map 출력을 하기 위한 부분이나 빌드 환경에서는 더이상 디버깅을 할 필요가 없으니 삭제합니다.
devServer는 webpack-dev-server의 환경 설정을 위한 부분입니다. 빌드 환경에서는 사용하지 않으니 삭제합니다.
webpack.config.js에서는 path를 undefined 로 설정했지만, 이제 빌드 결과물을 출력해야 하니 출력할 폴더를 지정합니다.
path 환경 설정값은 절대 경로로 입력해야 하기 때문에 path를 이용해서 현재 webpack이 수행되는 폴더(__dirname)의 하위 폴더 dist를 지정했습니다.

8.2. npm(yarn) script 수정 - package.json 수정

/* package.json */
{
  "name": "webpack-demo",
  "version": "1.0.0",
  "description": "webpack-demo",
  "scripts": {
    "dev": "webpack-dev-server",
    "build": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "copy-webpack-plugin": "^5.0.2",
    "css-loader": "^2.1.1",
    "file-loader": "^3.0.1",
    "html-webpack-plugin": "^3.2.0",
    "style-loader": "^0.23.1",
    "url-loader": "^1.1.2",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0",
    "webpack-dev-server": "^3.2.1"
  }
}

"build" : "webpack --config webpack.prod.js" 한줄 추가 했습니다. 이제 빌드 파일만 생성하면 되니, webpack-dev-server를 사용할 필요가 없습니다.
webpack의 기본 설정 파일은 webpack.config.js이기 때문에 webpack에 --config 옵션으로 빌드 설정 파일인 webpack.prod.js를 지정합니다.

8.3. 첫번째 빌드

npm run build

dist 폴더에 빌드 결과물이 생성된 것이 확인됩니다.

9. Clean webpack plugin 사용

처음 dist 폴더에 빌드하고 난 다음 다시빌드를 하면 , 이전 빌드된 결과물 중 새로 빌드되는 파일들을 덮어 씌워지게 됩니다.
하지만 원본이 삭제되는 등의 이유로 다시 빌드가 되지 않는 파일들이 있다면 dist 폴더에 남아 있게 되죠.
적은 가능성이기는 하지만 차후 보안 위험이 될 수 도 있습니다. 또 그냥 안쓰는 파일이 빌드 폴더에 남아 있는게 찝찝해서 이전에 빌드한 결과물을 삭제하는 플러그인이 clean webpack plugin 입니다.

9.1. Clean webpack plugin 설치

clean-webpack-plugin을 설치 하고 설정에 추가 하면 됩니다.

npm i -D clean-webpack-plugin

Webpack.config.js(webpack.prod.js) 수정

const CleanWebpackPlugin = require("clean-webpack-plugin");
// plugin 항목 아래 삽입
{
  plugin: [
    new CleanWebpackPlugin(),/* everything under <PROJECT_DIR>/dist/ will be removed. */
  ]
}

10. Webpack merge 사용

/* webpack.config.js */
"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const webpack = require("webpack");
 
module.exports = {
  mode: "development",
  entry: {
    app: "./src/index.js"
  },
  devtool: "cheap-module-eval-source-map",
  devServer: {
    contentBase: false,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    new webpack.HotModuleReplacementPlugin(),
    new CopyWebpackPlugin([
        {
          from: 'static',
          to: 'static'
        }
      ])
  ],
  output: {
    path: undefined,
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader:'url-loader',
        options: {
          limit: 10000,
          name: 'static/[name].[hash:7].[ext]'
        }
      }
    ]
  }
};
/* webpack.prod.js */
"use strict";
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
/* 삭제 const webpack = require("webpack"); */
 
module.exports = {
  mode: "production",
  entry: {
    app: "./src/index.js"
  },
  /* 삭제 devtool: "cheap-module-eval-source-map", */
  /* 삭제 devServer: {
    contentBase: false,
    hot: true
  }, */
  plugins: [
    new CleanWebpackPlugin(),/* everything under <PROJECT_DIR>/dist/ will be removed. */
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    /* 삭제 new webpack.HotModuleReplacementPlugin(), */
    new CopyWebpackPlugin([
        {
          from: 'static',
          to: 'static'
        }
      ])
  ],
  output: {
    path: path.resolve(__dirname, "dist"), /* 변경 undefined, */
    filename: "[name].js"
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader:'url-loader',
        options: {
          limit: 10000,
          name: 'static/[name].[hash:7].[ext]'
        }
      }
    ]
  }
};

두 파일을 비교해 보면, 개발과 빌드 환경에서 차이는,
Wepack-dev-server와 Webpack-cli 사용 때문에 devServer 설정을 위한 부분과
빌드한 파일을 저장하는 부분만 차이날 뿐 상당히 많은 부분이 동일한 내용으로 작성된 것을 알 수 있습니다.
사실 간단한 내용만 설정하여 webpack에서 많은 종류의 loader나 plugin을 사용하지 않았기 때문에 이 이정도 이지, 만약 더 많은 loader와 Plugin을 사용했다면 webpack 설정 파일의 내용에 중복되는 설정의 내용이 더 많아 질 것 입니다.

공통되는 부분을 webpack.common.js 파일로 만들고, 빌드에 필요한 설정만 wepback.prod.js, 개발에 필요한 설정만 webpack.dev.js 파일로 만들기로 했습니다.
그리고 개발 할때는 webpack.dev.js 파일과 webpack.common.js 파일을 사용하고
빌드 할때는 webpack.prod.js 파일과 webpack.common.js 사용하기로 했습니다.
그렇다면, 2개의 webpack 설정 파일을 병합 해주는 도구가 필요한데, 그 때 사용하는 플러그인이 webpack merge입니다.

10.1. webpack merge 설치

npm i -D webpack-merge

10.2. webpack.common.js 파일 생성

webpack.config.js와 webpack.prod.js의 동일한 부분만 복사해서 webpack.common.js 파일을 생성합니다.

"use strict";
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
 
module.exports = {
  entry: {
    app: "./src/index.js"
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "index.html",
      inject: true
    }),
    new CopyWebpackPlugin([
      {
        from: 'static',
        to: 'static'
      }
    ])
  ],
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          'style-loader',
          'css-loader'
        ]
      },
      {
        test: /\.(png|svg|jpg|gif)$/,
        loader:'url-loader',
        options: {
          limit: 10000,
          name: 'static/[name].[hash:7].[ext]'
        }
      },
      {
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader'}
      }
    ]
  },
  node: {
    fs: 'empty'
  }
};

10.3. webpack.dev.js 파일 생성

webpack.config.js 이름을 webpack.dev.js 로 변경하고, 기존 webpack.config.js에서 공통 부분을 제외하고 webpack merge를 추가한 설정 파일을 생성합니다.

"use strict"
const merge = require("webpack-merge");
const webpack = require("webpack");
const common = require("./webpack.common.js");
 
module.exports = merge(common, {
    mode: "development",
    devtool: "cheap-eval-source-map",
    devServer: {
        contentBase: false,
        hot: true
    },
    plugins:[
        new webpack.HotModuleReplacementPlugin()
    ],
    output: {
        path: undefined,
        filename: "[name].js"
    }
});

10.4. webpack.prod.js 수정

webpack.prod.js에서 똑같이 공동 설정 부분을 삭제 한 다음 webpack-merge로 병합합니다.

"use strict"
const merge = require('webpack-merge');
const common = require('./webpack.common.js');
const path = require("path");
const CleanWebpackPlugin = require("clean-webpack-plugin");
 
module.exports = merge(common, {
  mode: "production",
  plugins: [
    new CleanWebpackPlugin()
  ],
  output: {
      path: path.resolve(__dirname, "dist"),
      filename: "[name].js"
  }
});

10.5. package.json 수정

script 부분을 수정합니다.

"scripts": {
    "dev": "webpack-dev-server --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },