webpack loader

fe_sw·2022년 8월 24일
0

Webpack

목록 보기
2/4
post-thumbnail

webpack이 웹 애플리케이션을 해석할 때, js로 만든 모듈 뿐 아니라, 모든 웹 자원들도 전부 모듈로 본다.

import 구문을 사용하면 이 모듈들을 js 코드 안으로 가져올 수 있는데 이 이유는 webpack의 loader의 역할 덕분이다.

웹 자원 중에서 js 파일이 아닌 HTML, CSS, IMG, FONT 등을 변환할 수 있도록 도와주는 속성이다.

css-loader

웹팩은 모든것을 모듈로 바라보기 때문에 자바스크립트 뿐만 아니라 스타일시트로 import 구문으로 불러 올수 있다.

CSS 파일을 자바스크립트에서 불러와 사용하려면 CSS를 모듈로 변환하는 작업이 필요하다. css-loader가 그러한 역할을 가능하게 해준다.

//app.js
import "./style.css"
//style.css
body {
  background-color: green;
}
//설치
$ npm install -D css-loader
//webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/, // .css 확장자로 끝나는 모든 파일
        use: ["css-loader"], // css-loader를 적용한다
      },
    ],
  },
}

style-loader

모듈로 변경된 스타일 시트는 돔에 추가되어야만 브라우져가 해석할 수 있다.
css-loader로 처리하면 자바스크립트 코드로만 변경되었을 뿐 돔에 적용되지 않았기 때문에 스트일이 적용되지 않았다.

style-loader는 자바스크립트로 변경된 스타일을 동적으로 돔에 추가하는 로더이다.
배열로 설정하면 뒤에서부터 앞으로 순서대로 로더가 동작한다. 위 설정은 모든 .css 확장자로 끝나는 모듈을 읽어 들여 css-loader를 적용하고 그 다음 style-loader를 적용한다.

//설치
$ npm install -D style-loader
//webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"], // style-loader를 앞에 추가한다
      },
    ],
  },
}

file-loader

소스코드에서 사용하는 모든 파일을 모듈로 사용하게끔 할 수 있다.
파일을 모듈 형태로 지원하고 웹팩 아웃풋에 파일을 옮겨주는 것이 file-loader가 하는 일이다.
CSS에서 url() 함수에 이미지 파일 경로를 지정할 수 있는데 웹팩은 file-loader를 이용해서 이 파일을 처리한다.

//app.js
import "./style.css"
//style.css
body {
  background-image: url(bg.png);
}
//설치
$ npm i file-loader
//webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.png$/, // .png 확장자로 마치는 모든 파일
        loader: "file-loader", // 파일 로더를 적용한다
      },
    ],
  },
}

웹팩이 .png 파일을 발견하면 file-loader를 실행할 것이다. 로더가 동작하고 나면 아웃풋에 설정한 경로로 이미지 파일을 복사된다.

(파일명이 해쉬코드로 변경 되었다. 캐쉬 갱신을 위한 처리로 보인다.) file-loader 옵션을 조정해서 경로를 바로 잡아 주어야 한다.

//webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.png$/, // .png 확장자로 마치는 모든 파일
        loader: "file-loader",
        options: {
          publicPath: "./dist/", // prefix를 아웃풋 경로로 지정
          name: "[name].[ext]?[hash]", // 파일명 형식
        },
      },
    ],
  },
}

publicPath 옵션: file-loader가 처리하는 파일을 모듈로 사용할 때 경로 앞에 추가되는 문자열이다.

name 옵션: 로더가 파일을 아웃풋에 복사할때 사용하는 파일 이름이다. 기본적으로 설정된 해쉬값을 쿼리스트링으로 옮겨서 'bg.png?6453a9c65953c5c28aa2130dd437bbde' 형식으로 파일을 요청하도록 변경했다.

url-loader

사용하는 이미지 갯수가 많다면 네트웍 리소스를 사용하는 부담이 있고 사이트 성능에 영향을 줄 수도 있다. 만약 한 페이지에서 작은 이미지를 여러 개 사용한다면 Data URL Schema을 이용하는 방법이 더 나은 경우도 있다.

이미지를 Base64로 인코딩하여 문자열 형태로 소스코드에 넣는 형식이다.url-loader는 이러한 처리를 자동화해주는 녀석이다.

//설치
$ $ npm install -D url-loader
//webpack.config.js:
{
  test: /\.png$/,
  use: {
    loader: 'url-loader', // url 로더를 설정한다
    options: {
      publicPath: './dist/', // file-loader와 동일
      name: '[name].[ext]?[hash]', // file-loader와 동일
      limit: 5000 // 5kb 미만 파일만 data url로 처리
    }
  }
}

babel-loader

실무 환경에서는 바벨을 직접 사용하는 것보다는 웹팩으로 통합해서 사용하는 것이 일반적이다. 로더 형태로 제공하는데 babel-loader가 그것이다.

//설치
$ $ npm install -D babel-loader
// webpack.config.js:
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "babel-loader", // 바벨 로더를 추가한다
      },
    ],
  },
}

.js 확장자로 끝나는 파일은 babel-loader가 처리하도록 설정했다. 사용하는 써드파티 라이브라리가 많을수록 바벨 로더가 느리게 동작할 수 있는데 node_modules 폴더를 로더가 처리하지 않도록 예외 처리했다.

폴리필 사용 설정을 했다면 core-js도 설치해야한다. 웹팩은 바벨 로더가 만든 아래 코드를 만나면 core-js를 찾을 것이기 때문이다.

npm i core-js
require("core-js/modules/es6.promise")
require("core-js/modules/es6.object.to-string")

sass-loader

Sass / SCSS 파일을로드하고 CSS로 컴파일한다.

//설치
$ npm i sass-loader node-sass
//webpack.config.js:
  module: {//로더 js뿐만아닌 다른파일도 모듈로처리해서 번들해줌
    rules: [
      {
        test: /\.(scss|css)$/, //로더가 처리해야될 파일들의 패턴(정규표현식)
        use: [
          process.env.NODE_ENV === "production"
            ? MiniCssExtractPlugin.loader
            :"style-loader", //style-loader:자바스크립트파일에서 css파일을 불러올수 있음(html파일에서 css직접불러오기 안해도됨)
          "css-loader", //css파일을 만나면 css-loader가 처리함
          "sass-loader" //sass,scss파일 처리
        ],
      },
    ],
  },

0개의 댓글