> Hello World !!!

     

@syaku

Webpack setting - install & setting #1

Webpack setting - install & setting #1

프론트엔드 개발시 사용되는 웹팩에 대한 자세히 알아본다. 워낙 유명한 개발 도구여서 설명은 생략하고 사용하기 위한 설치와 설정에 대해 자세하게 다뤘다.

webpack 1 과 webpack 2 이상은 사용법이 다르니 주의한다. 내용에 사용한 정식 버전은 4.1.1 이다.

패키지 관리자는 yarn 을 사용한다. npm 을 사용해도 상관없지만 본문 내용은 yarn 을 기반으로 하고 있다.

npm 이 아닌 yarn 을 사용하려면 설치한다. -g 는 전역으로 사용할 수 있게 설치한다는 의미이다. 한번 설치하면 어디서든 명령어를 사용할 수 있다.

$ sudo npm install -g yarn

yarn init

yarn 을 초기화 명령으로 package.json 설정 파일을 생성할 수 있다.

$ yarn init

대충 입력해도 나중에 수정할 수 있다.

package.json

{
  "name": "security-react",
  "version": "1.0.0",
  "author": {
    "name": "Syaku (최석균)",
    "email": "syaku1220@gmail.com",
    "url": "http://syaku.tistory.com"
  },
  "main": "index.js",
  "license": "MIT"
}

해당 폴더 즉 프로젝트 폴더에 위와 같은 파일이 생성된다.

webpack install

웹팩을 설치한다. 웹팩 1과 웹팩 2 이상은 완전 다르니 꼭 웹팩 4이상을 설치해야 한다.

https://webpack.js.org/guides/installation/

$ yarn add webpack webpack-cli -D
  • webpack-cli : 터미널, 콘솔에서 입력한 명령어에 따라 webpack 을 실행시켜주는 패키지

-D 는 개발 모드시 사용되는 패키지에 설치되고 package.json devDependencies 에 설치 패키지가 포함된다. 개발시에만 의존되는 패키지들의 모음이다. 설치가 완료되면 아래와 같은 devDependencies 에 두개의 패키지가 추가된다.

package.json

{
  "name": "security-react",
  "version": "1.0.0",
  "author": {
    "name": "Syaku (최석균)",
    "email": "syaku1220@gmail.com",
    "url": "http://syaku.tistory.com"
  },
  "main": "index.js",
  "license": "MIT",
  "devDependencies": {
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.11"
  }
}

npm 이나 yarn 에서 긴 명령어를 매번 입력하기 귀찮으면 아래와 같이 작성하면 해당 속성을 명령어로 사용할 수 있다.

"scripts": {
    "start": "webpack"
}

그리고 터미널에서는 아래와 같이 사용하면 된다. npm 에서는 run 과 함께 입력해야 하지만 yarn 에서는 run 을 생략할 수 있다.

$ yarn start

위와 같이 실행하면 webpack 설정 파일을 만들지 않아 오류가 발생한다.

이제 웹팩 설정 파일을 만들고 Hello World 를 출력하는 자바스크립트와 css, font 그리고 image 파일을 모두 뭉치는 작업(번들링)을 해본다.

css-loader & style-loader & file-loader

https://webpack.js.org/guides/asset-management/

css 번들링을 위해 3개의 로더가 필요하다. 당장 css 대상이 없어서 패키지를 설치하여 번들링될 대상으로 사용하고 번들링 로더를 설치한다.

$ yarn add boostrap font-awesome

많이 사용되는 UI 컴포넌트 프레임워크 bootstrap 과 다양한 아이콘을 제공하는 font-awesome 을 설치하였다.

$ yarn add css-loader style-loader file-loader -D

웹팩 로더 설정에 추가하면 된다. webpack.config.js 파일을 만들고 아래와 같이 입력한다.

const path = require('path'); // node.js 내장 패키지

module.exports = {
  entry: './src/index.js',
  output: {
    filename: '[name].js?hash=[hash]',
    path: path.resolve(__dirname, 'dist'),
  },

  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['css-loader', 'style-loader'],
      },
      {
        test: /\.(png|jpg|gif)$/,
        use: ['file-loader'],
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2)$/,
        use: ['file-loader'],
      },
    ],
  },
};

webpack 옵션에 대한 전체 설명 : https://webpack.js.org/configuration/

  • entry : 번들링 대상이며 최초로 읽어지는 시작 파일을 설정한다. 해당 파일에 import 되는 모든 js,css,image 등등 파일을 하나로 모아진다. (entry 설정에 따라 하나 이상이 될 수 있다.) [name] entry 이름(기본값: main)으로 치환하고, [hash] hash 값을 생성하여 치환한다. hash 값을 사용하면 브라우저 캐시 사용시 중복되는 파일을 다시 로드될 수 있게 하기 위함이다. 파일명은 main.js 이지만 실제 html 삽입되면 main.js?hash=47466c3de072202ce9f8형태로 사용된다.
  • output : 모아진 모든 파일 즉 최종적으로 완료된 파일을 해당 경로에 생성한다.
  • modules : 설정 로더에 따라 모아주는 작업을 한다. 파일 타입에 맞는 로더를 사용해야 한다.
  • plugins : 번들링 전이나 후에 해야할 일들을 플러그인을 사용하여 처리한다.

test 속성에는 대상이 될 파일을 찾기 위한 정규화표현식을 사용하여 설정할 수 있다.

./src/index.js

import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/css/font-awesome.css';

document.write('Hello World!!! 안녕하세요~');

yarn start 하면 dist 폴더에 index.js 파일이 생성된다. css 내용도 index.js 에 포함되어 있고 index.html 도 없어 브라우저에서 볼 수가 없는 상태이다. 그래서 css 는 하나의 style.css 파일로 분리하고 index.html 생성하여 자동으로 스크립트와 스타일시트 파일이 주입되게 하여 브라우저에서 열어보도록 하자.

extract-text-webpack-plugin & html-webpack-plugin

extract-text-webpack-plugin 는 모아진 파일을 내용 일부를 추출하여 별도의 파일을 생성하고 html-webpack-plugin 는 html 에 템플릿에 최종적을 완성된 파일을 자동적으로 주입해주는 역활을 한다. 그외 더 다양한 기능이 있으니 아래 링크를 참조한다.

https://webpack.js.org/plugins/extract-text-webpack-plugin/#src/components/Sidebar/Sidebar.jsx
https://webpack.js.org/guides/output-management/#setting-up-htmlwebpackplugin

$ yarn add extract-text-webpack-plugin html-webpack-plugin -D

해당 패키지는 웹팩 플러그인이므로 플러그인 속성에 설정을 추가하면 된다.

./src/index.html 파일을 생성한다.

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>security-react</title>
</head>
<body>
</body>
</html>

webpack.config.js 아래 코드를 추가한다.

// 상단에 패키지를 불러온다.
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

... skip ...

  plugins: [
    new ExtractTextPlugin('[name].css?hash=[hash]'),
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
  ],

... skip ...

  module: {
    rules: [

      {
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader',
        }),
      },

    ],
  },
};

yarn start 명령을 입력하면 dist 폴더에 index.html 와 css 파일이 생성된 것을 확인할 수 있다.

브라우저를 통해 dist/index.html 파일을 실행하면 원하는 결과를 확인할 수 있을 것이다.

그리고 다음 작업을 진행한다.

clean-webpack-plugin

빌드할때 마다 dist 새로운 파일이 생성되어 누적된다. 생성된 파일명 hash 값이 달라서인데 빌드할때 dist 폴더를 삭제하도록 설정하면 된다.

$ yarn add clean-webpack-plugin -D

해당 패키지는 웹팩 플러그인이므로 플러그인 속성에 설정을 추가하면 된다.

const CleanWebpackPlugin = require('clean-webpack-plugin');

plugins: [
  new CleanWebpackPlugin(['dist']),
],

webpack-dev-server

https://webpack.js.org/configuration/dev-server
https://webpack.js.org/guides/hot-module-replacement/

현재까지 모듈 번들링을 위한 설정 작업이였다. 실제 개발시 효율적인 작업을 진행하기 위한 설정방법을 설명한다.

webpack dev server 는 아래와 같은 일들을 처리한다.

  • 개발용 로컬 서버를 구동한다. (설정으로 외부 접근도 가능하다. 운영 서버로 사용하지는 말자)
  • 소스 코드가 변경되면 자동으로 빌드하고 브라우저를 새로고침해준다. 또한 빌드가 캐싱되어 처음보다 빠른 빌드업을 통해 결과를 확인할 수 있다.
  • 프락시 설정으로 백엔드 API 서버를 프락시로 설정하여 연동할 수 있다.

흔히 사용되는 기능들이고 그외에도 많은 기능들을 제공하고 있다.

$ yarn add webpack-dev-server -D

webpack.config.js

일반 설정

module.exports = {
  devServer: {
    publicPath: '', // 공개 경로 output 의 publicPath 와 동일하지만 경로 끝에 / 제거해야 한다.
    contentBase: path.resolve(__dirname, 'dist'), // 서비스될 경로
    port: 8088,
    host: 'localhost',
  },
};

세부 설정

module.exports = {
  devServer: {
    publicPath: '',
    contentBase: path.resolve(__dirname, 'dist'), // 서비스될 경로
    historyApiFallback: true, // react router 를 사용하기 위한 설정
    port: 8088,
    disableHostCheck: true, // 호스트를 검사하지 않는 다.
    host: '0.0.0.0', // 외부에서 접근할 수 있다.
    proxy: {
      '/api': {
        target: 'http://localhost:8080', // API Server
        pathRewrite: { '^/api': '' }, // proxy path 를 제거하도록 다시 쓴다.
        secure: false,
        prependPath: true, // target 에 경로를 사용한다.
      },
    },
  },
};

proxy: { '/api': 는 요청 경로가 /api 로 시작하는 모든 경로를 target 경로로 치환한다.

 /api/user 요청하면 실제 http://localhost:8080/user 경로가 요청된다. pathRewrite 속성으로 /api 를 제거했고 prependPath 속성으로 target 경로로 사용했기 때문이다.

devServer 실행하기 위한 package.json 의 scripts 에 실행 작업을 아래와 같이 추가한다.

package.json

  "scripts": {
    "build": "webpack -p --color --progress",
    "dev": "webpack-dev-server -d --color --progress"
  },

build : start 실행명을 의미에 맞게 변경 dev : devServer 실행하기 위한 명령

-p 는 product mode 로 실행한다. 실제 운영서버에 배포될때 유용한 빌드 설정을 제공한다.

다음 포스팅에서 정리하겠지만 webpack-dev-server 는 개발 환경에서 사용하는 기능이다. 그래서 운영 환경의 webapck 설정에는 포함하지 않아야 한다. 이유는 webpack-dev-server를 작동하기 위한 일부 코드가 삽입되기 때문이다. 운영 환경에는 최적화된 소스가 배포되어야 한다. 그 외 일부 개발환경에 사용되는 플러그인이나 로더들도 마찬가지로 잘 분리해주는 것이 좋다. 환경에 따른 설정은 다음 포스팅에 더 자세하게 다뤄보겠다.

이번 포스팅은 여기까지이며 다음에는 리액트와 바벨에 대한 설명을 다루도록 한다. :)

최종 소스: https://github.com/syakuis/webpack/tree/master/basic

변경된 사항

4.6.0 버전으로 업데이트되면서 변경사항이 있다.

webpack 최적화 mode 기능

https://webpack.js.org/concepts/mode

mode 설정으로 운영 환경이나 개발 환경에 적합한 설정이 최적화된다.

extract-text-webpack-plugin

4.0.0-beta.0 버전을 설치해야 한다. @next 작성하면 최근 개발된 버전을 설치할 수 있다.

$ yarn add extract-text-webpack-plugin@next -D

CommonsChunkPlugin 제거되고 splitChunks 옵션을 사용한다.

기존 플러그인에 사용했던 webpack.optimize.CommonsChunkPlugin 를 아래와 같이 사용할 수 있다.

optimization: {
    splitChunks: { ... option ... }
}

자세한 설명은 https://webpack.js.org/plugins/split-chunks-plugin/ 참고한다.