6. webpack-dev-server


webpack은 여러 개 파일을 하나의 파일로 합쳐주는 번들러(bundler)다.
webpack-dev-server는 운영환경과 동일하게 배포전에 서버 구동을 하여 테스트할 수 있는 환경을 제공해 준다.

환경 설정

  • node: v12.16.3
  • npm: 6.14.5
  • webpack: 4.43.0
  • webpack-cli: 3.3.11

모듈 구조

설치 & 사용법

1
$ npm install -D webpack-dev-server

app.js 수정

app.js
1
2
3
4
import "./style.scss";

const name = "jaehyun";
console.log(name);

style.scss 수정

style.scss
1
2
3
4
5
@import "./src/variables.scss";

body {
background-color: $brand-color;
}

variables.scss$brand-color: #2ac1bc;변수값을 설정 했다.

package.json에 추가

package.json
1
2
3
"scripts": {
"start": "webpack-dev-server --progress",
}

서버 구동

package.json에 등록한 명령어로 실행을 하여 서버를 구동한다.

1
$ npm start

  • localhost:8080 으로 접속해 보면 결과물을 확인할 수 있고, webpack 서버는 파일 변화를 감지하면 webpack 을 재빌드 하여 브라우져를 갱신하여 변화된 코드로 화면을 보여준다.

기본 옵션 설정

webpack 설정 파일의 devServer 객체에 서버 옵션을 설정할 수 있다.

기본 옵셜 설명

webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
module.exports = {
devServer: {
contentBase: path.join(__dirname, "dist"),
publicPath: "/",
host: "dev.domain.com",
overlay: true,
port: 8081,
stats: "errors-only",
historyApiFallback: true,
}
}
옵션 설명
contentBase 정적파일 제공 경로(기본값: webpack의 output)
publicPath 브라우저 접근 경로(기본값: / )
host Domain 환경을 맞춤
overlay 빌드시 에러나 경고를 브라우저에 출력
port 개발 서버 포트 번호를 설정
stats 상태 메시지 수준 설정(‘none’, ‘errors-only’, ‘minimal’, ‘normal’, ‘verbose’)
historyApiFallBack history api를 사용하여 SPA 개발시 404가 발생하면 index.html으로 리다이렉트

webpack.config.js 수정

webpack.config.js
1
2
3
4
devServer: {
overlay: true,
stats: "errors-only",
},

서버 구동

서버 구동후 에러를 발생시켜 브라우저 화면에 에러가 출력을 확인한다.

Hot Module Replacement(HMR)

Hot Module Replacement는 브라우저 전체 화면을 갱신하지 않고, 변경된 모듈만 갱신한다.

설정

devServer.hot 속성을 설정

webpack.config.js
1
2
3
devServer: {
hot:true,
},

서버 구동

1
$ npm start

서버 구동을 완료하고, src/style.scss 파일에 배경화면을 값을 변경하여 브라우저가 갱신을 하지 않고 배경색깔이 변경되는 것을 확인

핫로딩 지원하는 로더

Hot Module Replacemnt 지원하는 로더는 참고

style-loader
1
2
3
4
if (module.hot) {
module.hot.accept(
${loaderUtils.stringifyRequest(this, `!!${request}`)},
...

style-loader코드에서 보면 if (module.hot) 값이 true일 경우 module.hot.accept함수를 사용한다.

Mode

웹팩을 최적화 하는 방법중에 mode 값을 설정하는 방식

옵션 설명
development NamedChunksPlugin, NamedModulesPlugin
production FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin, TerserPlugin
  • 설정한 mode 옵션 값에 따라 사용하는 플러그인이 다르게 사용된다.

webpack.config.js mode 값 추가

webpack.config.js
1
2
3
4
5
const mode = process.env.NODE_ENV || "development"; // 기본값을 `development` 설정

module.exports = {
mode,
}

package.json 수정

package.json
1
2
3
4
5
6
{
"scripts": {
"start": "webpack-dev-server --progress",
"build": "NODE_ENV=production webpack --progress" // 개발시 NODE_ENV=development로 변경
}
}

빌드

1
$ npm run build

운영체제가 window일 경우 ‘NODE_ENV’은(는) 내부 또는 외부 명령, 실행할 수 있는 프로그램, 또는
배치 파일이 아닙니다.
메세지 발생시 $ npm install -g win-node-env 설치

NODE_ENV=production 빌드 결과

NODE_ENV=development 빌드 결과

  • 두 결과물을 보면 NODE_ENV=productionNODE_ENV=development로 빌드 시 사용되는 플러그인이 다른 것을 확인할 수 있다.

optimazation 속성으로 최적화

빌드 과정에서 커스터마이징할 수 있는 optimazation속성을 사용.

optimize-css-assets-webpack-plugin

optimize-css-assets-webpack-plugin은 css 파일을 압축하는 최적화 플러그인

설치

1
$ npm install -D optimize-css-assets-webpack-plugin

webpack.config.js에 추가

webpack.config.js
1
2
3
4
5
6
7
8
9
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
optimization: {
minimizer: mode === 'production' ? [ // mode가 production일 경우만 실행
new OptimizeCSSAssetsPlugin(),
] : [],
},
}
  • optimization.minimizerOptimizeCSSAssetsPlugin을 전달해서 css파일을 압축하도록 하는 플러그인

NODE_ENV=production 빌드

1
$ npm run build

  • 빌드 후 css 코드가 압축된 것을 확인할 수 있다.

terser-webpack-plugin

TerserWebpackPlugin는 debugger 구문을 제거하거나, 옵션 값으로 console.log도 배포전에 삭제하는 플러그인이다.

설치

1
$ npm install -D terser-webpack-plugin

webpack.config.js에 추가

webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
optimization: {
minimizer: mode === 'production' ? [ // mode가 production일 경우만 실행
new TerserPlugin({
terserOptions: {
compress: {
drop_console: true, // console.log를 제거
}
}
}),
] : [],
},
}

NODE_ENV=production 빌드

1
$ npm run build

  • 빌드 후 consol.log를 검색해보면 삭제 된 것을 확인할 수 있다.

코드 스플리팅

코드를 하나로 압축 하는 것 외에 코드 결과물을 여러개로 쪼개서 다운로드 속도를 빠르게 할 수 있다

초기 프로젝트에는 크게 사용할 일이 없지만, 프로젝트 파일이 커지면 적용하면 좋은 거지 꼭 해야 되는 것은 아니다.
코드 스플리팅에대해서 간단하게만 설명하고, 다이나익 임포트에 대해서는 설명을 안한다.

result.js 파일 생성

result.js
1
2
3
4
5
6
7
8
9
export default {
hide() {
console.log("hide");
},

show() {
console.log("show");
},
};

app.js 수정

app.js
1
2
3
4
5
6
7
8
import "./style.scss";
import result from "./result";

const name = "jaehyun";
console.log(name);

result.hide();
result.show();

중복 코드 제거

SplitChunksPlugin는 코드를 분리할때 중복을 예방하는 플러그인이다.

webpack.config.js에 추가

webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
module.exports = {
entry: {
main: "./src/app.js",
result: "./src/result.js"
},
optimization: {
splitChunks: {
chunks: "all", // 중복 제거 플로그인 옵션
},
},
}

빌드

1
$ npm run build

index.html 에 result.js 추가 확인

externals

externals은 패키지로 제공될때 이미 빌드 과정을 한것을 제외시켜 최적화 시키는 방법이다.
axios같은 써드파티 라이브러리로 예를 들어보자.

CopyWebpackPlugin & axios설치

(CopyWebpackPlugin)[https://webpack.js.org/plugins/copy-webpack-plugin/]은 파일을 복사하는 플러그인이다.

1
$ npm install -D copy-webpack-plugin
1
$ npm install -D axios

webpack.config.js에 추가

webpack.config.js:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
externals: {
axios: 'axios',
},
plugins: [
new CopyPlugin({
patterns: [
{
from: "./node_modules/axios/dist/axios.min.js",
to: "./axios.min.js" // 목적지 파일에 들어간다
},
],
}),
]
}

axois를 번들에 포함 하지 않고 빌드하며, to는 목적지로 파일을 복사한다.

index.html에 추가

index.html
1
2
3
4
...
<script type="text/javascript" src="axios.min.js"></script>
</body>
</html>

빌드

1
$ npm run build

소스코드

참조