Loader

2020. 7. 9. 12:57웹/Webpack

로더(Loader)

  • 웹팩은 모든 파일을 모듈로 인식(Javascript, css, image, 폰트 등)

  • import 구문을 통해 자바스크립트 코드 안으로 가져올 수 있음

  • 타입스크립트 같은 다른 언어를 자바스크립트 문법으로 변환해주거나 이미지를 data URL 형식의 문자열로 변환

  • 이러한 기능이 가능한 이유는 Loader 의 역할

 

로더 등록

  • webpack.config.js

module.exports = {
    ...
    // 로더는 모듈 객체에 rules 에 추가 가능
    module: {
        rules : [
            // 객체 선언
            {
                test: /\.js$/, // 로더가 처리해야할 파일들의 패턴(정규 표현식)
                use: [         // 사용할 로더 명시
                    path.resolve('./test-loader.js')
                ]
            }
        ]
    }
}

 

 

 

자주 사용하는 로더

css-loader, style-loader

  • css-loader : CSS 파일을 자바스크립트에서 불러와 사용하기 위한 모듈로 변환하는 작업 수행

  • style-loader : css-loader에 의해 자바스크립트 코드안의 문자열 형태로 변환된 코드를 HTML에 주입해주는 작업 수행

 

설치

npm install style-loader css-loader

 

webpack.config.js

module.exports = {
    ...
    module: {
        rules : [
            {
                test: /\.css$/,
                // 순서는 배열의 뒤에서 부터 앞
                use: [         
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
}

 

 

file-loader 

  • 파일을 모듈 형태로 지원하고 웹팩 아웃풋에 파일을 옮겨주는 역할

 

※ 파일명이 헤쉬값으로 변경

  • 웹펙은 빌드할 때마다 유니크한 값으로 생성

  • 캐쉬 갱신을 위함

  • 정적 파일의 경우 브라우저에서 성능을 위해 캐시

 

설치

npm install file-loader

 

webpack.config.js

module.exports = {
    ...
    module: {
        rules : [
            {
                test: /\.(png|jpg)$/,
                loader: 'file-loader',
                options: {
                    publicPath: './dist/',      // 파일 로더가 처리하는 파일을 모듈로 사용했을 때 경로 앞에 추가하는 경로
                    name: '[name].[ext]?[hash]' // 파일 로더가 아웃풋에 파일을 복사할 때 사용하는 파일이름, [원본파일].[확장자명][해쉬값]
                }
            }
        ]
    }
}

 

 

url-loader

  • 사용하는 이미지가 많아지면 네트워크 부담, 성능에 영향

  • 파일 사이즈가 작은 대상을 Data URI Scheme(Base64로 인코딩하여 문자열 형태)로 소스 코드에 넣는 형식이 성능 측면에서 더 나을 수 있음

  • 이러한 형식으로 변환해주는 처리를 자동으로 해주는 역할

 

설치

npm install url-loader

 

webpack.config.js

module.exports = {
    ...
    module: {
        rules : [
            {
                test: /\.(png|jpg|gif|svg)$/,
                loader: 'url-loader',
                options: {
                    publicPath: './dist/',       // 파일 로더가 처리하는 파일을 모듈로 사용했을 때 경로 앞에 추가하는 경로
                    name: '[name].[ext]?[hash]', // 파일 로더가 아웃풋에 파일을 복사할 때 사용하는 파일이름, [원본파일].[확장자명][해쉬값]
                    limit: 7000                  // 7KB, 파일을 처리할 때의 크기 제한, 7KB 미만일 경우 url-loader 가처리, 이상일 경우 file-loader 가 처리
                }
            }
        ]
    }
}

 

 

 

테스트

git :  https://github.com/Donghui-Lee/wepback-test/tree/add-loader

 

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
    <h1>Webpack 테스트</h1>

    <div class="container">
      <div class="top"></div>
      <div class="content"></div>
    </div>

    <!-- Webpack 으로 빌드한 자바스크립트 파일 로딩-->
    <script type="text/javascript" src="dist/main.js"></script>
  </body>
</html>

 

main.css

body {
  background-color: gray;
}

.top {
  background-image: url("./images/dog.png");
  background-repeat: no-repeat;
  width: 100%;
  height: 250px;
}

 

app.js

import MainController from "./controllers/MainController.js";
import "./main.css";

document.addEventListener("DOMContentLoaded", () => {
    new MainController();
});

 

MainController.js(controllers/MainController.js)

import ContentView from '../views/ContentView.js';

export default class MainController {
    constructor() {
        const contentViewEl = document.querySelector('.content');
        this.contentView = new ContentView(contentViewEl);
    }
}

 

View.js(views/View.js)

export default class View {
    constructor(el) {
        if (!el) throw el;

        this.el = el;
        return this;
    }

    hide() {
        this.el.style.display = "none";
        return this;
    }

    show() {
        this.el.style.display = "";
        return this;
    }
}

 

ContentView.js(views/ContentView.js)

import View from './View.js';
import defaultImage from "../images/default-image.jpg";

export default class ContentView extends View {
    constructor(el) {
        super(el);
        this.render();
    }

    render() {
        this.el.innerHTML = `<img src="${defaultImage}" />`;
    }
}

 

webpack.config.js

const path = require("path");

module.exports = {
  mode: "development",
  entry: {
    main: "./src/app.js",
  },
  output: {
    filename: "[name].js",
    path: path.resolve("./dist"),
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
      {
        test: /\.(jpg|png)$/,
        loader: "url-loader",
        options: {
          name: "[name].[ext]?[hash]",
          publicPath: "./dist",
          limit: 7000, // 7KB 미만은 url-loader 그 이상은 file-loader 처리
        },
      },
    ],
  },
};

 

실행결과

 

 

 

 

 

 

참고

http://jeonghwan-kim.github.io/js/2017/05/15/webpack.html

' > Webpack' 카테고리의 다른 글

Webpack - 기본 환경  (0) 2020.07.07
Module 개념  (0) 2020.07.07
Webpack 개념  (0) 2020.07.07