티스토리 뷰

javascript/webpack

webpack 강좌 5. 개발 Development

이브라히모비치 2018. 9. 10. 13:58




이전 강좌의 코드를 활용합니다.


가이드를 계속 따라오고 있다면, 웹팩 기초에 대한 확실한 이해가 있을 것입니다. 계속 진행하기 전에, 삶을 보다 쉽게 만들어 줄 개발 환경 설정을 살펴보겠습니다.


이 가이드에서 활용되는 도구들은 오직 개발development 환경을 위한 것이므로, 프로덕션 환경에서는 사용하지 마십시오.


소스맵 사용 Using source maps

웹팩이 소스 코드를 번들로 묶을때, 에러와 경고를 원래 경로로 추적하기 어려워질 수 있습니다. 만약 3개의 파일들(a.js, b.js, c.js)을 하나의 bundle.js 파일로 묶으려 하고, 이 중 하나의 파일이 에러를 포함하고 있다고 가정했을때, stack trace는 단순히 bundle.js를 가리킬 것입니다. 이것은 어떤 소스파일이 에러를 가지고 있는지 알고자 할때 도움되지 않습니다.


에러와 경고를 쉽게 추적하기 위해, Javascript는 컴파일된 코드를 원본 소스 코드로 매핑하는 source map을 지원합니다. 만약 b.js 에서 에러가 발생되었다면, 소스맵은 정확히 그것을 알려줍니다.


소스맵을 사용하는데는 다양한 옵션들이 존재합니다. 사용자 요구에 맞게 구성할 수 있도록 확인하십시오.


이 가이드에서는 (프로덕션용은 아니지만) 실무에 도움이 되는 inline-source-map 옵션을 사용하겠습니다.


webpack.config.js

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

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
+   devtool: 'inline-source-map',
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Development'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };


디버그를 위해 print.js 파일에 에러를 만들어 줍니다.


src/print.js

  export default function printMe() {
-   console.log('I get called from print.js!');
+   cosnole.log('I get called from print.js!');
  }


npm run build를 실행하면, 이런식으로 컴파일 할 것입니다.


Hash: 7bf68ca15f1f2690e2d1
Version: webpack 3.1.0
Time: 1224ms
          Asset       Size  Chunks                    Chunk Names
  app.bundle.js    1.44 MB    0, 1  [emitted]  [big]  app
print.bundle.js    6.43 kB       1  [emitted]         print
     index.html  248 bytes          [emitted]
   [0] ./src/print.js 84 bytes {0} {1} [built]
   [1] ./src/index.js 403 bytes {0} [built]
   [3] (webpack)/buildin/global.js 509 bytes {0} [built]
   [4] (webpack)/buildin/module.js 517 bytes {0} [built]
    + 1 hidden module
Child html-webpack-plugin for "index.html":
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
        + 2 hidden modules


이제 index.html을 브라우저에서 열어, 버튼을 클릭하고 console창에 찍힌 에러를 확인 하십시오.


Uncaught ReferenceError: cosnole is not defined
    at HTMLButtonElement.printMe (print.js:2)


에러 내용과 발생한 파일(print.js), 라인 넘버(2)까지 알 수 있습니다. 이슈를 해결하기 위해 어디를 봐야 하는지 명확히 알 수 있기 때문에 매우 유용합니다.


개발 도구 선택 Choosing a Development Tool

몇몇 에디터에는 지금부터 다룰 도구들 중 일부를 방해할 수 있는 "safe write" 기능이 있습니다. 이 이슈를 해결하려면 하단 에디터 설정을 참고하십시오.


컴파일 해야 할때마다 수동으로 npm run build를 실행하는 것은 번거롭습니다.


웹팩에는 코드가 변경될때 마다 자동으로 컴파일 해주는 몇가지 옵션들이 있습니다.


1. webpack’s Watch Mode

2. webpack-dev-server

3. webpack-dev-middleware


대부분의 겨우 webpack-dev-server를 사용하고 싶겠지만, 이 옵션 모두를 알아봅시다.


감시 모드 사용 Using Watch Mode

당신은 웹팩에게 의존성 그래프에 포함된 모든 파일의 변경을 “감시” 하라고 지시할 수 있습니다. 이 파일들 중 하나가 업데이트되면, 수동으로 전체 빌드를 실행하지 않아도 코드는 다시 컴파일 됩니다. 


npm script에 webpack 감시watch 모드를 추가해 보겠습니다.


package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
+     "watch": "webpack --watch",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }


이제 커맨드 라인에서 npm run watch를 실행하고 웹팩이 어떻게 컴파일 하는지 지켜보십시오. 커맨드 라인이 종료되지 않는 걸 확인할 수 있습니다. 왜냐하면 현재 스크립트가 파일들을 감시하고 있기 때문입니다.


웹팩이 파일을 지켜보고 있는 동안, 이전에 발생 시켰던 에러를 제거해 보겠습니다.


src/print.js

  export default function printMe() {
-   cosnole.log('I get called from print.js!');
+   console.log('I get called from print.js!');
  }


이제 파일을 저장하고 터미널을 확인해 보십시오. 웹팩이 변경된 모듈을 자동으로 다시 컴파일하는 것을 볼 수 있습니다!


유일한 장점은 변화를 확인하기 위해 브라우저를 새로고침 해야 한다는 것입니다. 이 또한 자동으로 된다면 훨씬 좋아질 것입니다. webpack-dev-server가 정확히 이렇게 동작하니, 알아보도록 하겠습니다.


webpack-dev-server 사용

webpack-dev-server는 간단한 웹서버와 실시간 리로딩 기능을 지원합니다. 설치해 보겠습니다.

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


config파일을 변경해 dev 서버에서 파일을 찾을 위치를 지정하십시오.


webpack.config.js

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

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    devtool: 'inline-source-map',
+   devServer: {
+     contentBase: './dist'
+   },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Development'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist')
    }
  };


webpack-dev-server를 통해 dist 디렉토리의 파일들을 localhost:8080 에서 제공하겠다는 의미입니다.


webpack-dev-server는 컴파일 후 어떤 파일도 생성하지 않습니다. 대신 번들 파일들을 메모리에 보관하고 서버 루트 경로에 마운트된 실제 파일처럼 제공합니다. 만약 다른 경로의 번들 파일을 페이지에서 찾으려면, dev 서버 구성의 publicPath 옵션을 변경할 수 있습니다. 


쉬운 dev 서버 실행을 위해 다음과 같이 script를 추가해 봅시다.


package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --watch",
+     "start": "webpack-dev-server --open",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "xml-loader": "^1.2.1"
    }
  }

 

이제 커맨드 라인에서 npm start로 실행할 수 있고 브라우저가 자동으로 로딩되는 것을 확인할 수 있습니다. 아무 소스 파일이나 수정하고 저장하면, 웹 서버는 컴파일 후 자동으로 리로드 됩니다. 시도해 보십시오!


webpack-dev-server는 다양하게 구성 가능한 옵션들이 제공됩니다. 자세한 내용은 documentation을 참고 하십시오.


이제 서버가 작동하고 있으므로, Hot Module Replacement를 시도해 볼 수 있습니다!

 

webpack-dev-middleware 사용

webpack-dev-middleware 는 웹팩에서 처리된 파일을 서버로 내보내는 래퍼입니다. webpack-dev-server 내부에서 사용되지만, 원할 경우 더 많은 사용자 설정을 허용하는 개별 패키지로 사용할 수 있습니다. express 서버와 webpack-dev-middleware 를 결합한 예제를 살펴 보겠습니다.


expresswebpack-dev-middleware를 설치합니다.

npm install --save-dev express webpack-dev-middleware


미들웨어가 잘 동작할 수 있도록 웹팩 구성configuration 파일의 일부를 수정해야 합니다.


webpack.config.js

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

  module.exports = {
    entry: {
      app: './src/index.js',
      print: './src/print.js'
    },
    devtool: 'inline-source-map',
    devServer: {
      contentBase: './dist'
    },
    plugins: [
      new CleanWebpackPlugin(['dist']),
      new HtmlWebpackPlugin({
        title: 'Output Management'
      })
    ],
    output: {
      filename: '[name].bundle.js',
      path: path.resolve(__dirname, 'dist'),
+     publicPath: '/'
    }
  };


publicPath는 파일들이 http://localhost:3000 서버로 잘 올라갔는지 확인하기 위해 서버 스크립트 내부에서 사용됩니다. 포트 번호는 추후 지정하겠습니다. 다음 단계는 express 서버 설정입니다.


project

  webpack-demo
  |- package.json
  |- webpack.config.js
+ |- server.js
  |- /dist
  |- /src
    |- index.js
    |- print.js
  |- /node_modules

server.js

const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');

const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);

// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
  publicPath: config.output.publicPath
}));

// Serve the files on port 3000.
app.listen(3000, function () {
  console.log('Example app listening on port 3000!\n');
});


이제 좀 더 쉽게 서버를 실행하기 위한 npm 스크립트를 추가합니다.


package.json

  {
    "name": "development",
    "version": "1.0.0",
    "description": "",
    "main": "webpack.config.js",
    "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "watch": "webpack --watch",
      "start": "webpack-dev-server --open",
+     "server": "node server.js",
      "build": "webpack"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "devDependencies": {
      "clean-webpack-plugin": "^0.1.16",
      "css-loader": "^0.28.4",
      "csv-loader": "^2.1.1",
      "express": "^4.15.3",
      "file-loader": "^0.11.2",
      "html-webpack-plugin": "^2.29.0",
      "style-loader": "^0.18.2",
      "webpack": "^3.0.0",
      "webpack-dev-middleware": "^1.12.0",
      "xml-loader": "^1.2.1"
    }
  }


터미널에서 npm run server를 실행하면 이렇게 나올 것입니다.


Example app listening on port 3000!
webpack built 27b137af6d9d8668c373 in 1198ms
Hash: 27b137af6d9d8668c373
Version: webpack 3.0.0
Time: 1198ms
          Asset       Size  Chunks                    Chunk Names
  app.bundle.js    1.44 MB    0, 1  [emitted]  [big]  app
print.bundle.js    6.57 kB       1  [emitted]         print
     index.html  306 bytes          [emitted]
   [0] ./src/print.js 116 bytes {0} {1} [built]
   [1] ./src/index.js 403 bytes {0} [built]
   [2] ./node_modules/lodash/lodash.js 540 kB {0} [built]
   [3] (webpack)/buildin/global.js 509 bytes {0} [built]
   [4] (webpack)/buildin/module.js 517 bytes {0} [built]
Child html-webpack-plugin for "index.html":
         Asset    Size  Chunks  Chunk Names
    index.html  544 kB       0
       [0] ./node_modules/html-webpack-plugin/lib/loader.js!./node_modules/html-webpack-plugin/default_index.ejs 538 bytes {0} [built]
       [1] ./node_modules/lodash/lodash.js 540 kB {0} [built]
       [2] (webpack)/buildin/global.js 509 bytes {0} [built]
       [3] (webpack)/buildin/module.js 517 bytes {0} [built]
webpack: Compiled successfully.


브라우저를 열어 http://localhost:3000 으로 접속해 보십시오. 웹팩 앱이 실행되고 작동할 것입니다.


Hot Module Replacement 에 대해 자세히 알고 싶다면, 가이드를 참고 하십시오.


에디터 설정 Adjusting Your Text Editor

코드 자동 컴파일 기능을 사용하면 저장할때 문제가 발생할 수 있습니다. 일부 에디터의 "safe write" 기능이 재컴파일을 방해할 수 있기 때문입니다. 


이 기능을 끄려면 아래 리스트를 참고 하십시오.


  • Sublime Text 3 : 환경설정에서 atomic_save : “false" 를 추가 하십시오.
  • JetBrains IDEs (e.g. WebStorm) : Preferences > Appearance & Behavior > System Settings 의 “Use safe write” 체크를 해제 하십시오.
  • vim : 설정에서 :set backupcopy=yes 를 추가 하십시오.


마치며

코드를 자동으로 컴파일 하는 방법과 개발 서버를 쉽게 띄우는 방법을 알아 보았습니다.




출처 : https://webpack.js.org/







댓글
Kakao 다음웹툰 / 웹표준 및 ft기술, 웹접근성 / 세아이 아빠, 제주 거주 중..
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday