๊ด€๋ฆฌ ๋ฉ”๋‰ด

C-log

๐Ÿ”งWebpack : Plugin ๋ณธ๋ฌธ

โš›๏ธReact/๐Ÿ”งFront-Dev-Environment

๐Ÿ”งWebpack : Plugin

4:Bee 2024. 8. 20. 19:47
728x90

 ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ๋ฒˆ๋“ค๋œ ๊ฒฐ๊ณผ ํ•˜๋‚˜๋งŒ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ๋ฒˆ๋“ค๋œ js๋ฅผ ๋‚œ๋…ํ™” ํ•œ๋‹ค๊ฑฐ๋‚˜ ํŠน์ • ํ…์ŠคํŠธ๋ฅผ ์ถ”์ถœํ•˜๋Š” ์šฉ๋„๋ก ์‚ฌ์šฉํ•œ๋‹ค. 


My-Webpack-Plugin

class MyWebpackPlugin {
  apply(compiler) {
    compiler.hooks.done.tap('MyWebpackPlugin', stats => {
      console.log('MyPlugin: done');
    })
  }
}

module.exports = MyWebpackPlugin;

์œ„์™€ ๊ฐ™์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์ปค์Šคํ…€ ํ•  ์ˆ˜ ์žˆ๋‹ค.

1. class MyWebpackPlugin : Webpack ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ํด๋ž˜์Šค ํ˜•ํƒœ๋กœ ์ •์˜ํ•ด์•ผ ๋œ๋‹ค.

2. apply(compiler) { ... } : Webpack ํ”Œ๋Ÿฌ๊ทธ์ธ์€ apply ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค. apply ๋ฉ”์„œ๋“œ๋Š” Webpack์ด ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ๋•Œ ํ˜ธ์ถœ๋˜๋ฉฐ ์ด ๋ฉ”์„œ๋“œ๋Š” Webpack์˜ compiler ๊ฐ์ฒด๋ฅผ ์ธ์ˆ˜๋กœ ๋ฐ›์•„ ์ปดํŒŒ์ผ๋Ÿฌ์™€ ๋นŒ๋“œ ํ”„๋กœ์„ธ์Šค ์ค‘ ๋ฐœ์ƒํ•˜๋Š” ์—ฌ๋Ÿฌ ์ด๋ฒคํŠธ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

3. compiler.hooks.done.tap('MyWebpackPlugin', stats => { ... }) : ์ด ์ค„์€ Webpack์˜ done ํ›…(hook)์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ์‹คํ–‰๋˜๋Š” ์ž‘์—…์„ ์ •์˜ํ•œ๋‹ค.

  • compiler.hooks.done: Webpack์˜ done ํ›…์€ ์ปดํŒŒ์ผ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ์‹คํ–‰๋œ๋‹ค.
  • tap('MyWebpackPlugin', stats => { ... }): ์ด ๋ฉ”์„œ๋“œ๋Š” ํŠน์ • ํ›…์— ํ•จ์ˆ˜๋ฅผ ๋“ฑ๋ก(tap)ํ•œ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์˜ ์ด๋ฆ„์ด๋ฉฐ ๋‘ ๋ฒˆ์งธ ์ธ์ˆ˜๋Š” ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ์‹คํ–‰๋  ์ฝœ๋ฐฑ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
    • 'MyWebpackPlugin': ๋“ฑ๋ก๋œ ํ•จ์ˆ˜์˜ ์ด๋ฆ„์œผ๋กœ, ๋””๋ฒ„๊น… ๋ฐ ๋กœ๊น… ์‹œ ์œ ์šฉํ•˜๋‹ค.
    • stats => { ... }: ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋กœ, stats ๊ฐ์ฒด๋Š” ์ปดํŒŒ์ผ ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” ๋นŒ๋“œ๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ์‹คํ–‰๋œ๋‹ค.

Plugin์ด ๋ฒˆ๋“ค ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ด์œ ๋Š” ์›นํŒฉ ๋‚ด์žฅ ํ”Œ๋Ÿฌ๊ทธ์ธ์ธ BannerPlugin์„ ํ†ตํ•ด์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์ด๋ฅผ ์ฐธ์กฐํ•ด์„œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ปค์Šคํ…€ ํ•ด๋ณด์ž.

class MyWebpackPlugin {
  apply(compiler) {
    compiler.plugin('emit', (compilation, callback) => {
      const source = compilation.assets['main.js'].source();
      console.log(source);
      // compilation.assets['main.js'].source = () => {
      //   const banner = [
      //     '/**',
      //     ' * ์ด๊ฒƒ์€ BannerPlugin์ด ์ฒ˜๋ฆฌํ•œ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.',
      //     ' * Build Date: 2019-10-10',
      //     ' */'
      //   ].join('\n');
      //   return banner + '\n\n' + source;
      // }

      callback();
    })
  }
}

module.exports = MyWebpackPlugin;

์œ„์™€ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๊ณ  build๋ฅผ ํ•˜๊ฒŒ ๋˜๋ฉด error๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ ์ด์œ ๋Š” `compiler.plugin`์ด๋ผ๋Š” ๋ช…๋ น์–ด๊ฐ€ webpack5์—์„œ๋Š” ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ  ์‚ญ์ œ๊ฐ€ ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด webpack5๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์˜ฌ๋ฐ”๋ฅธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

class MyWebpackPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback) => {
      const source = compilation.assets['main.js'].source();
      console.log(source);
      // compilation.assets['main.js'].source = () => {
      //   const banner = [
      //     '/**',
      //     ' * ์ด๊ฒƒ์€ BannerPlugin์ด ์ฒ˜๋ฆฌํ•œ ๊ฒฐ๊ณผ์ž…๋‹ˆ๋‹ค.',
      //     ' * Build Date: 2019-10-10',
      //     ' */'
      //   ].join('\n');
      //   return banner + '\n\n' + source;
      // }

      callback();
    })
  }
}

module.exports = MyWebpackPlugin;

 `compiler.plugin` ์ด๋ผ๋Š” ์ฝ”๋“œ๋ฅผ ๋Œ€์‹ ํ•ด์„œ ์ด๋ ‡๊ฒŒ ์ฝ”๋“œ๋ฅผ `compiler.hooks.emit.tapAsync('MyPlugin', (compilation, callback)`๋ฅผ ์ด์šฉํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ build๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด์ œ `console.log(source)`์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

/*
 * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
 * This devtool is neither made for production nor for readable output files.
 * It uses "eval()" calls to create a separate source file in the browser devtools.
 * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
 * or disable the default devtool with "devtool: false".
 * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
 */
/******/ (() => { // webpackBootstrap
/******/        "use strict";
/******/        var __webpack_modules__ = ({

/***/ "./.yarn/__virtual__/css-loader-virtual-16d7c22a15/0/cache/css-loader-npm-6.11.0-d945f9f4c0-bb52434138.zip/node_modules/css-loader/dist/cjs.js!./src/app.css":
/*!*******************************************************************************************************************************************************************!*\
  !*** ./.yarn/__virtual__/css-loader-virtual-16d7c22a15/0/cache/css-loader-npm-6.11.0-d945f9f4c0-bb52434138.zip/node_modules/css-loader/dist/cjs.js!./src/app.css ***!
  \*******************************************************************************************************************************************************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {

eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, 
/* -- ์ดํ•˜์ƒ๋žต -- */

๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด build๋œ main.js์™€ ์ผ์น˜ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ BannerPlugin๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ๋™์ž‘ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์•˜๋‹ค. ์ด์ œ ๋ฐฉ๊ธˆ ์ž‘์„ฑํ•œ ์ฝ”๋“œ์—์„œ ์ฃผ์„์œผ๋กœ ์ฒ˜๋ฆฌ๊ฐ€ ๋˜์–ด ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ํ™œ์šฉํ•ด build๋œ ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด์ž. ์ฃผ์„์„ ์ฒ˜๋ฆฌํ•˜๊ณ  build๋ฅผ ํ•˜๋ฉด ์ •์ƒ์ ์œผ๋กœ build๋Š” ๋˜์ง€๋งŒ main.js์— ์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•œ ์ฃผ์„์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด์— webpack ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ฐพ์•„๊ฐ€๋ณด๋ฉฐ gpt์™€ ํ•จ๊ป˜ ์ด๋ฅผ ํ•ด๊ฒฐ ํ–ˆ๋‹ค. ์ˆ˜์ •๋œ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

class MyWebpackPlugin {
  apply(compiler) {
    compiler.hooks.emit.tapAsync('MyWebpackPlugin', (compilation, callback) => {
      console.log('This is an example plugin!');
      const source = compilation.assets['main.js'].source();
      const banner = ['/* This is an example plugin! */'].join('\n');
      const updatedSource = banner + '\n\n' + source;
      // ์ˆ˜์ •๋œ ์†Œ์Šค๋ฅผ assets์— ๋‹ค์‹œ ์„ค์ •
      compilation.assets['main.js'] = {
        source: () => updatedSource,
        size: () => updatedSource.length
      };
      console.log('Banner added to main.js');
      callback();// ๋น„๋™๊ธฐ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ์Œ์„ ์•Œ๋ฆผ
    })
  }
}

module.exports = MyWebpackPlugin;

์ด์ „ ๋ฒ„์ „ ๋ฐฉ์‹์ธ return์„ ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ๋ฒ•๊ณผ ๋‹ฌ๋ฆฌ webpack5์—์„œ๋Š” key, value์ฒ˜๋Ÿผ ๊ฐ์ฒดํ™”ํ•ด์„œ ๊ฐ’์„ ๋„˜๊ฒจ์ฃผ๋‹ˆ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. complication์€ ๊ฐ์ฒด๋Š” Webpack์ด ๋ชจ๋“ˆ์„ ๋ถ„์„ํ•˜๊ณ  ๋ฒˆ๋“ค๋งํ•˜๋Š” ๊ณผ์ •์—์„œ ์‚ฌ์šฉ๋˜๋ฉฐ ๊ฐ ๋ชจ๋“ˆ๊ณผ ํŒŒ์ผ์ด ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๊ณ  ์—ฐ๊ฒฐ๋˜๋Š”์ง€์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•œ๋‹ค.

๊ฐ•์˜ ์ปค๋ฎค๋‹ˆํ‹ฐ๋ฅผ ๋ณด๋‹ˆ ๋งŽ์€ ์ˆ˜๊ฐ•์ƒ๋“ค์ด ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด๋‹ฌ๋ผ๊ณ  ํ•˜๊ณค ์žˆ์ง€๋งŒ ๊ทธ ์‹œ๊ฐ„์„ ๊ธฐ๋‹ค๋ฆด ์ˆ˜ ์—†์–ด์„œ ๊ณต์‹๋ฌธ์„œ์™€ gpt๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ถฉ๋ถ„ํžˆ ํ•ด๊ฒฐ ํ• ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์•„๋ž˜ ์ด๋ฏธ์ง€๋Š” webpack์ด ์ „๋ฐ˜์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€๋ฅผ ์‹œ๊ฐ์ ์œผ๋กœ ํ‘œ๊ธฐํ•ด๋ณธ ์ด๋ฏธ์ง€์ด๋‹ค. ๋ช‡๋ช‡ ์ •๋ณด๋“ค์„ ๋นผ๋†“๊ธด ํ–ˆ์ง€๋งŒ ์–ด๋–ค ๋Š๋‚Œ์ธ์ง€ ์•Œ ๊ฒƒ์ด๋‹ค.

๋‹น์—ฐํžˆ entry๋Š” ๋จผ์ € ์„ค์ •์ด ๋˜์–ด ์žˆ์„ ๊ฒƒ์ด๋‹ค.

 

Writing a Plugin | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

 

728x90

'โš›๏ธReact > ๐Ÿ”งFront-Dev-Environment' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

๐Ÿ”งWebpack : Babel  (0) 2024.08.24
๐Ÿ”งWebpack : ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” Plugin  (0) 2024.08.20
๐Ÿ”งWebpack : url-loader  (0) 2024.07.19
๐Ÿ”งWebpack : file-loader  (0) 2024.07.17
๐Ÿ”งWebpack : css-loader, style-loader  (0) 2024.07.17
Comments