Webpack - Loader & Plugin

Hoon·2023년 9월 25일
0

FrontEnd

목록 보기
1/7
post-thumbnail

Webpack : build 라는 과정을 통해 의존성이 있는 여러개의 자바스크립트 파일을 하나로 합쳐주는 번들러 의 일종. (이렇게 합쳐진 파일을 번들 이라한다.)


Install

아래의 명령어를 통해 프로젝트를 생성해주고 webpack 을 설치해준다.

$ mkdir webpack-project
$ cd webpack-project
$ npm init
$ npm install webpack webpack-cli

package.json 의 srcipts 에 build 를 추가해준다.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  ...
}

추가로 아래의 구조로 파일을 만들어주었다.
index.html 파일은 builddist 경로의 main.js 를 참조할 것이다.
(HtmlWebpackPlugin plugin을 사용하면 index.html 또한 dist 경로에 포함시킬수있음.)


webpack.config.js

webpack.config.js 파일을 생성해 아래와 같이 webpack 에 대한 설정을 해준다.
위에서 생성한 ./src/app.js 경로의 파일을 진입점 삼아 output 의 경로로 번들링 한다는 설정이다.

// webpack.config.js
const path = require("path");

module.exports = {
  mode: "development",
  // 모듈의 시작점 (진입점)
  entry: {
    main: "./src/app.js",
  },
  // 번들될 파일의 정보
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
  },
};

이제 build 를 해보면 해당 설정에 맞는 결과를 확인할 수 있다.


Loader

Loader : Webpack 이 웹 애플리케이션을 해석할 때 javascript 파일이 아닌 웹 자원 (HTML, CSS, Image, 폰트 등) 들을 Webpack 이 해석할 수 있도록 처리해주는 속성

  • 웹팩은 모든 파일을 모듈로 바라보는데, Loader 가 모든 파일을 javascript의 모듈처럼 변환하여 번들에 포함시킨다.

아래의 코드는 간단한 Loader 의 예시로 console.log 를 alert 로 바꿔주는 my-webpack-loader.js 를 만들어보았다.

// my-webpack-loader.js
module.exports = function myWebpackLoader(content) {
  return content.replace("console.log(", "alert(");
};

위에서 만든 Loaderwebpack.config.js 에 추가해준다.

// webpack.config.js
module.exports = {
	...
    module: {
    	rules: [
      		{ 
                // 처리할 파일들
            	test: /\.js$/, 
                // 적용할 로더들의 배열
                use: path.resolve(__dirname, "./my-webpack-loader.js") 
            },
    	],
    }
    ...
}

이제 아래의 app.js 를 생성해주고 build 를 해준다.

// app.js
console.log("this file is app.js");

build 시에 my-webpack-loader 가 처리되어 결과물인 main.js 에서는 console.log 가 alert 로 처리된것을 볼 수 있다.

아래는 Webpack 에서 대표적인 Loader 들이다.

  • css-loader : js파일에서 css파일을 불러오기 위한 로더

  • style-loader : DOM에 css style을 넣어주기 위한 로더

  • file-loader : 파일을 모듈로 사용할 수 있게 해주는 로더

  • url-loader : 파일을 base64 URL로 변환해주는 로더 (설정 limit 초과 시 file-loader로 동작)

이러한 Loader 들은 아래와 같이 설정할 수 있다.

// webpack.config.js
module.exports = {
	...
  	module: {
      rules: [
        ...
        {
          test: /\.css$/,
          use: ["style-loader", "css-loader"], // 뒤에서 부터 실행
        },
        {
          test: /\.(png|jpg|gif|svg)$/,
          loader: "url-loader",
          options: {
            name: "[name].[ext]?[hash]",
            limit: 2000, // 2kb
          },
        },
        ...
      ],
   },
}

Plugin

Plugin : Loader 가 파일 단위로 해석하고 처리하는 반면, Plugin 은 번들된 결물들을 역할을 한다. (번들된 결과물이 최종파일이 되기전에 후처리를 수행)

아래의 코드는 간단한 Plugin 의 예시로 번들된 결과물인 main.js 의 맨 윗부분에 주석처리를 해주는 MyWebpackPlugin 을 만들어보았다.

class MyWebpackPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync("MyWebpackPlugin", (compilation, callback) => {
      const source = compilation.assets["main.js"].source();

      const newSource = [
        "/**",
        " * 이것은 내가 만든 Plugin이 처리한 결과입니다.",
        ` * Build Date: ${new Date().toLocaleString()}`,
        " */",
        source,
      ].join("\n");

      compilation.assets["main.js"] = {
        source: () => newSource,
      };

      callback();
    });
  }
}

module.exports = MyWebpackPlugin;

위에서 만든 Pluginwebpack.config.js 에 추가해준다.

// webpack.config.js
const MyWebpackPlugin = require("./my-webpack-plugin");

module.exports = {
	...
    plugins: [
    	new MyWebpackPlugin(),
    ],
    ...
}

build 시에 my-webpack-plugin 이 처리되어 결과물인 main.js 의 맨 위에 주석처리가 추가된 것을 확인할 수 있다.

아래는 Webpack 에서 대표적인 Plugin 들이다.

  • webpack.BannerPlugin : 결과물에 빌드 정보, 커밋, 만든이 등의 정보를 추가할 수 있다.

  • webpack.DefinePlugin : 모든 자바스크립트 코드에서 접근이 가능한 전역 변수를 선언할 수 있다.

  • HtmlWebpackPlugin : 따로 분리하여 번들한 css파일js파일을 각각 html 파일link 태그, script태그추가해줘야 한다. HtmlWebpackPlugin은 이것을 자동화 해준다. (/dist에 css, js를 주입한 index.html 생성)

  • CleanWebpackPlugin : 빌드 이전 결과물을 제거하고 빌드를 수행할 수 있다.

  • MiniCssExtractPlugin : 빌드시 CSS를 별도의 파일로 추출하는 플러그인으로, JS파일 당 하나의 CSS파일을 작성한다.

profile
개발자 Hoon입니다

0개의 댓글