티스토리 뷰




처음부터 가이드를 잘 따라왔다면 “Hello webpack” 이 보여지는 작은 프로젝트를 가지고 있을 것입니다. 이제 몇몇 다른 에셋들(이미지등)을 병합시키는 방법을 알아보겠습니다.


이전 웹팩에서는, 프론트엔드 개발자들이 이 에셋들을 처리하고,  /src  폴더에서  /dist  /build  폴더로 옮기기 위해 그런트나 걸프같은 툴을 사용했습니다. 같은 아이디어가 Javascript 모듈에 사용되었지만, 웹팩같은 툴은 동적으로 모든 의존성 번들을 처리 했습니다(의존성 그래프 생성). 이것이 대단한 이유는, 이제 모든 모듈이 의존성을 명시적으로 선언하고, 사용하지 않는 모듈들을 번들에서 제외할 수 있기 때문입니다.


웹팩의 가장 멋진 기능 중 하나는 Javascript 외에 로더가 있는 어떤 종류의 파일도 포함할 수 있다는 점입니다. 이것은 위에서 열거한 Javascript의 동일한 장점들이 웹사이트나 웹앱을 빌드하는 모든것에 적용 할수있다는 것을 의미 합니다. CSS 설정에 이미 익숙할 것 같으니, 그것으로 시작해 보겠습니다.


설정 Setup

시작하기 전에 프로젝트를 살짝 수정하겠습니다 :


dist/index.html

  <!doctype html>
  <html>
    <head>
-    <title>Getting Started</title>
+    <title>Asset Management</title>
    </head>
    <body>
      <script src="./bundle.js"></script>
    </body>
  </html>

Loading CSS

Javascript 모듈 내에서 CSS를  import  하려면 module 구성에 style-loadercss-loader를 인스톨하고 추가해야 합니다. 

npm install --save-dev style-loader css-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
+   module: {
+     rules: [
+       {
+         test: /\.css$/,
+         use: [
+           'style-loader',
+           'css-loader'
+         ]
+       }
+     ]
+   }
  };


웹팩은 특정 로더에서 어떤 파일을 찾고 제공할지 정하기 위해 정규식을 사용합니다. 위의 경우 .css 를 확장자로 가지는 모든 파일이 style-loader css-loader 에 제공 됩니다.


이렇게 하면 해당 스타일에 따라 파일 안에서  import './style.css'  가 가능합니다. 모듈을 실행하면, <style> 태그와 문자열로 바뀐 CSS가 html 파일의 <head> 로 삽입되게 됩니다.


프로젝트에서 style.css를 만들고 index.js 로 import 해봅시다.


project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- style.css
    |- index.js
  |- /node_modules

src/style.css

.hello {
  color: red;
}

src/index.js

  import _ from 'lodash';
+ import './style.css';

  function component() {
    var element = document.createElement('div');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
+   element.classList.add('hello');

    return element;
  }

  document.body.appendChild(component());


빌드 명령을 실행하면

npm run build

Hash: 9a3abfc96300ef87880f
Version: webpack 2.6.1
Time: 834ms
    Asset    Size  Chunks                    Chunk Names
bundle.js  560 kB       0  [emitted]  [big]  main
   [0] ./~/lodash/lodash.js 540 kB {0} [built]
   [1] ./src/style.css 1 kB {0} [built]
   [2] ./~/css-loader!./src/style.css 191 bytes {0} [built]
   [3] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [4] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [5] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [6] (webpack)/buildin/global.js 509 bytes {0} [built]
   [7] (webpack)/buildin/module.js 517 bytes {0} [built]
   [8] ./src/index.js 351 bytes {0} [built]


index.html 파일을 브라우저에서 다시 열어보면 Hello webpack이 빨간색으로 바뀐것을 볼 수 있습니다. 웹팩이 어떤 작업을 했는지 확인하려면, 페이지 검사 도구를 열어서 head 태그를 보십시오. (페이지 소스를 확인하지 마세요. 아무 결과도 보여지지 않습니다.) 그러면 index.js로 불러온 스타일 블럭이 포함되어 있을 것입니다.


프로덕션의 더 나은 로드 타임을 위해 CSS를 최소화 하는 것을 할 수 있고, 대부분의 경우에는 그렇게 해야합니다. 그중 CSS의 거의 모든 특성을 위한 로더가 존재합니다 : postcss, sass, less 등


Loading Images

CSS파일은 사용하고 있습니다만, 배경이나 아이콘에 사용되는 이미지들은 어떨까요? file-loader를 사용하면 그것들을 시스템에 쉽게 병합할 수 있습니다.

npm install --save-dev file-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
+       {
+         test: /\.(png|svg|jpg|gif)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };


이제 import MyImage from './my-image.png’ 를 사용할때, 이 이미지는 처리되어 output 디렉토리로 추가되며, 이후 변수 MyImage 는 이미지의 최종 경로를 얻게 됩니다. 위에서 나온 css-loader를 사용하면, CSS 내부의 url('./my-image.png’)를 위한 비슷한 프로세스가 발생합니다. 로더는 이 이미지가 로컬 파일이라고 인지하고, './my-image.png’ 경로를 output 디렉토리의 최종 경로로 바꿉니다. html-loader는 동일한 방식 <img src="./my-image.png" /> 으로 다룹니다.


프로젝트에 이미지를 추가해보고 어떻게 동작하는지 살펴봅시다. 어떤 이미지라도 상관없습니다.


project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/index.js

  import _ from 'lodash';
  import './style.css';
+ import Icon from './icon.png';

  function component() {
    var element = document.createElement('div');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

+   // Add the image to our existing div.
+   var myIcon = new Image();
+   myIcon.src = Icon;
+
+   element.appendChild(myIcon);

    return element;
  }

  document.body.appendChild(component());

src/style.css

  .hello {
    color: red;
+   background: url('./icon.png');
  }


새 빌드를 만들고 index.html 파일을 다시 열어보세요.

npm run build

Hash: 854865050ea3c1c7f237
Version: webpack 2.6.1
Time: 895ms
                               Asset     Size  Chunks                    Chunk Names
5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
                           bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 242 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [6] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [7] (webpack)/buildin/global.js 509 bytes {0} [built]
   [8] (webpack)/buildin/module.js 517 bytes {0} [built]
   [9] ./src/index.js 503 bytes {0} [built]


만약 모든것이 잘 동작한다면, 배경에 사용한 아이콘과 Hello webpack 옆의 이미지를 살펴보십시오. 이 요소들을 검사해보면, 파일명이 5c999da72346a995e7e2718865d019c8.png 이런식으로 바뀐것을 확인할 수 있습니다. 이것은 웹팩이 src 폴더에서 파일들을 찾아 처리했다는 의미입니다.


로직상 다음 단계는 이미지 최소화와 최적화입니다. 이미지 로딩 프로세스에 대해 더 알고 싶다면 image-webpack-loaderurl-loader 를 살펴보십시오.


Loading Fonts

그럼 폰트같은 에셋들은 어떻게 할까요? 파일 및 url 로더는 로드한 모든 파일을 가져와서 빌드 디렉토리로 출력합니다. 즉 폰트를 포함한 모든 파일을 사용할 수 있음을 의미합니다. 폰트 파일을 다루기 위해 webpack.config.js 를 업데이트 해보죠.


webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(woff|woff2|eot|ttf|otf)$/,
+         use: [
+           'file-loader'
+         ]
+       }
      ]
    }
  };


폰트 파일을 프로젝트에 포함하세요.


project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- my-font.woff
+   |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules


로더가 구성되고 폰트가 있으면, @font-face 선언을 통해 이것을 통합할 수 있습니다. 로컬 url(..) 지시자가 이미지와 마찬가지로 웹팩에 의해 선택됩니다.


src/style.css

+ @font-face {
+   font-family: 'MyFont';
+   src:  url('./my-font.woff2') format('woff2'),
+         url('./my-font.woff') format('woff');
+   font-weight: 600;
+   font-style: normal;
+ }

  .hello {
    color: red;
+   font-family: 'MyFont';
    background: url('./icon.png');
  }


이제 새 빌드를 실행하고 폰트가 잘 적용되었는지 확인합니다.

npm run build

Hash: b4aef94169088c79ed1c
Version: webpack 2.6.1
Time: 775ms
                                Asset     Size  Chunks                    Chunk Names
 5c999da72346a995e7e2718865d019c8.png  11.3 kB          [emitted]
11aebbbd407bcc3ab1e914ca0238d24d.woff   221 kB          [emitted]
                            bundle.js   561 kB       0  [emitted]  [big]  main
   [0] ./src/icon.png 82 bytes {0} [built]
   [1] ./~/lodash/lodash.js 540 kB {0} [built]
   [2] ./src/style.css 1 kB {0} [built]
   [3] ./~/css-loader!./src/style.css 420 bytes {0} [built]
   [4] ./~/css-loader/lib/css-base.js 2.26 kB {0} [built]
   [5] ./src/MyFont.woff 83 bytes {0} [built]
   [6] ./~/style-loader/lib/addStyles.js 8.7 kB {0} [built]
   [7] ./~/style-loader/lib/urls.js 3.01 kB {0} [built]
   [8] (webpack)/buildin/global.js 509 bytes {0} [built]
   [9] (webpack)/buildin/module.js 517 bytes {0} [built]
  [10] ./src/index.js 503 bytes {0} [built]


index.html 파일을 다시 열고 Hello webpack 의 폰트가 바뀌었는지 확인하세요.


Loading Data

로드할 수 있는 또다른 유용한 에셋은 JSON, CSV, TSV, XML과 같은 데이터 파일입니다. 사실 JSON에 대한 지원은 NodeJS와 마찬가지로 내장되어 있습니다. import Data from './data.json’ 는 기본적으로 작동합니다. CSV, TSV, XML을 import 하기 위해서, csv-loaderxml-loader를 사용할 수 있습니다. 세가지 모두 작업해 보겠습니다.

npm install --save-dev csv-loader xml-loader

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            'style-loader',
            'css-loader'
          ]
        },
        {
          test: /\.(png|svg|jpg|gif)$/,
          use: [
            'file-loader'
          ]
        },
        {
          test: /\.(woff|woff2|eot|ttf|otf)$/,
          use: [
            'file-loader'
          ]
        },
+       {
+         test: /\.(csv|tsv)$/,
+         use: [
+           'csv-loader'
+         ]
+       },
+       {
+         test: /\.xml$/,
+         use: [
+           'xml-loader'
+         ]
+       }
      ]
    }
  };

project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
+   |- data.xml
    |- my-font.woff
    |- my-font.woff2
    |- icon.png
    |- style.css
    |- index.js
  |- /node_modules

src/data.xml

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Mary</to>
  <from>John</from>
  <heading>Reminder</heading>
  <body>Call Cindy on Tuesday</body>
</note>


이제 4가지 유형의 데이터(JSON, CSV, TSV, XML) 중 하나를 import 할 수 있으며, Data 변수에는 쉽게 사용할 수 있는 JSON 형태의 데이터가 포함되어 있습니다. 


src/index.js

  import _ from 'lodash';
  import './style.css';
  import Icon from './icon.png';
+ import Data from './data.xml';

  function component() {
    var element = document.createElement('div');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
    element.classList.add('hello');

    // Add the image to our existing div.
    var myIcon = new Image();
    myIcon.src = Icon;

    element.appendChild(myIcon);

+   console.log(Data);

    return element;
  }

  document.body.appendChild(component());


index.html 파일을 열어 개발자 도구의 console 창을 확인해보면, 불러온 데이터가 console에 찍혀있는 것을 확인할 수 있을 것입니다.

  

이것은 d3 같은 데이터 시각화 툴에서 특히 유용합니다. ajax요청을 보내거나 런타임때 데이터를 파싱하는 대신 빌드 프로세스를 진행할때 모듈에서 그것을 로드할 수 있습니다. 그러면 파싱된 데이터는 브라우저에 도달 하자마자 사용할 준비가 되어 있습니다.


Global Assets

지금까지 나왔던 것 중 가장 멋진 부분은, 이 방법으로 에셋을 로드하면 보다 직관적인 방법으로 모듈과 에셋을 그룹화할 수 있다는 것입니다. 모든 것이 포함된 전역 /assets 디렉토리에 의지하는 대신, 에셋을 사용하는 코드로 그룹을 묶을 수 있습니다. 예를 들어 이런 구조는 상당히 유용할 것 입니다.

- |- /assets
+ |– /components
+ |  |– /my-component
+ |  |  |– index.jsx
+ |  |  |– index.css
+ |  |  |– icon.svg
+ |  |  |– img.png


이 설정은 당신의 코드를 훨씬 더 이식성 있게 만듭니다. 만약 /my-component 를 다른 프로젝트에서 사용하고 싶다면, 단순히 그곳에 /components 디렉토리를 복사하거나 옮기면 됩니다. 어떤 외부 의존성을 설치하고 당신의 구성이 동일한 로더를 정의하는 한, 잘 동작할 것입니다.


하지만 예전 방식을 고수하거나 여러 컴포넌트(뷰, 템플릿, 모듈등)에서 공유하는 몇몇 에셋이 있다고 가정해봅시다. 여전히 이 에셋들을 기본 디렉토리에 저장하는 것은 가능합니다. 그리고 import를 보다 쉽게 만들어주는 aliasing까지도 사용할 수 있습니다.  


마무리 Wrapping up

다음 가이드에서는 여기서 사용한 에셋을 모두 사용하지는 않을 것이므로, 정리 후 다음 시간을 준비하겠습니다.


project

  webpack-demo
  |- package.json
  |- webpack.config.js
  |- /dist
    |- bundle.js
    |- index.html
  |- /src
-   |- data.xml
-   |- my-font.woff
-   |- my-font.woff2
-   |- icon.png
-   |- style.css
    |- index.js
  |- /node_modules

webpack.config.js

  const path = require('path');

  module.exports = {
    entry: './src/index.js',
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist')
    },
-   module: {
-     rules: [
-       {
-         test: /\.css$/,
-         use: [
-           'style-loader',
-           'css-loader'
-         ]
-       },
-       {
-         test: /\.(png|svg|jpg|gif)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(woff|woff2|eot|ttf|otf)$/,
-         use: [
-           'file-loader'
-         ]
-       },
-       {
-         test: /\.(csv|tsv)$/,
-         use: [
-           'csv-loader'
-         ]
-       },
-       {
-         test: /\.xml$/,
-         use: [
-           'xml-loader'
-         ]
-       }
-     ]
-   }
  };

src/index.js

  import _ from 'lodash';
- import './style.css';
- import Icon from './icon.png';
- import Data from './data.xml';
-
  function component() {
    var element = document.createElement('div');
-
-   // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');
-   element.classList.add('hello');
-
-   // Add the image to our existing div.
-   var myIcon = new Image();
-   myIcon.src = Icon;
-
-   element.appendChild(myIcon);
-
-   console.log(Data);

    return element;
  }

  document.body.appendChild(component());

  



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







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