@issue image minify using bun & webpack

joepasss·2023년 9월 26일
0

webpack

목록 보기
4/7
post-thumbnail

Attempt 01. ImageMinimizerWebpackPlugin 사용


웹팩 도큐먼트
여기서 imagemin 만 추가해서 사용할 예정이다.

웹팩이 이미지를 로딩할 수 없기 때문에 webpack asset 을 먼저 작성

{
	test: /\.(png|jpg|svg)$/,
	type: "asset",
	parser: {
		dataUrlCondition: {
		maxSize: 1024,
		},
	},
	generator: {
	filename: "images/[name].[contenthash:12][ext]",
	},
},

bun run build 를 해 주면, 오류 없이 번들링이 잘 되는 모습을 볼 수 있다.

이제 이미지 사이즈를 줄이기 위헤 관련 패키지 설치 (image-minimizer-webpack-plugin, imagemin)

bun add -D image-minimizer-webpack-plugin imagemin

lossy option 을 사용할 예정이므로

bun add -D imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant imagemin-svgo

도큐먼트에 작성된 코드를 거의 그대로 배껴서 작성

new ImageMinimizerPlugin({
        minimizer: {
          implementation: ImageMinimizerPlugin.imageminMinify,
          options: {
            // Lossless optimization with custom option
            // Feel free to experiment with options for better result for you
            plugins: [
              ["gifsicle"],
              ["mozjpeg"],
              ["pngquant"],
              // Svgo configuration here https://github.com/svg/svgo#configuration
              [
                "svgo",
                {
                  plugins: [
                    {
                      name: "preset-default",
                      params: {
                        overrides: {
                          removeViewBox: false,
                          addAttributesToSVGElement: {
                            params: {
                              attributes: [
                                { xmlns: "http://www.w3.org/2000/svg" },
                              ],
                            },
                          },
                        },
                      },
                    },
                  ],
                },
              ],
            ],
          },
        },
      }),

bun run build

ERROR in Error with 'images/header-image.5b361a0f2927.jpg': Command failed with ENOENT: node_modules/mozjpeg/vendor/cjpeg
spawn node_modules/mozjpeg/vendor/cjpeg ENOENT



ERROR in   Error: Child compilation failed:
  Module Error (from ./node_modules/image-minimizer-webpack-plugin/dist/loader.js):
  Error with 'images/header-image.jpg': Command failed with ENOENT: node_modules/mozjpeg/vendor/cjpeg
  spawn node_modules/mozjpeg/vendor/cjpeg ENOENT
  
  
  ModuleError: Module Error (from ./node_modules/image-minimizer-webpack-plugin  /dist/loader.js):
  Error with '/images/header-image.jpg': Command failed with ENOENT: node_modules/mozjpeg/vendor/cjpeg
  spawn node_modules/mozjpeg/vendor/cjpeg ENOENT
  
  
      at Object.emitError (node_modules/webpac  k/lib/NormalModule.js:614:6)
      at Object.loader (node_modules/image-min  imizer-webpack-plugin/dist/loader.js:161:12)
      at process.processTicksAndRejections (node:internal/process/task_queues:9  5:5)
  Error with 'images/header-image.5b361a0f2927.jpg': Command failed with ENOENT  : node_modules/mozjpeg/vendor/cjpeg
  spawn node_modules/mozjpeg/vendor/cjpeg ENOE  NT
  
  
  Error: Error with 'images/header-image.5b361a0f2927.jpg': Command failed with   ENOENT: node_modules/mozjpeg/vendor/cjpeg
  spawn node_modules/mozjpeg/vendor/cjpeg ENOE  NT
  
  
      at Object.imageminMinify [as implementation] (node_modules/image-minimizer-webpack-plugin/dist/utils.js:575:22)
      at process.processTicksAndRejections (node:internal/process/task_queues:9  5:5)
      at async worker (node_modules/image-minimizer-webpack-plugin/dist/worker.js:77:25)
      at async node_modules/image-minimizer-webpack-plugin/dist/index.js:327:18
  
  - NormalModule.js:614 Object.emitError
    [webpack]/[webpack]/lib/NormalModule.js:614:6
  
  - loader.js:161 Object.loader
    [webpack]/[image-minimizer-webpack-plugin]/dist/loader.js:161:12
  
  - task_queues:95 process.processTicksAndRejections
    node:internal/process/task_queues:95:5
  
  - Error with 'images/header-image.5b361a0f2927.jpg': Command failed with ENOE    NT: node_modules/mozjpeg/vendor/cjpeg
  
  - spawn node_modules/mozjpeg/vendor/cjpeg ENOENT
  
  - Error: Error with 'images/header-image.5b361a0f2927.jpg': Command failed with ENOENT: /node_modules/mozjpeg/vendor/cjpeg
  
  - spawn node_modules/mozjpeg/vendor/cjpeg ENOENT
  
  - utils.js:575 Object.imageminMinify [as implementation]
    [webpack]/[image-minimizer-webpack-plugin]/dist/utils.js:575:22
  
  - task_queues:95 process.processTicksAndRejections
    node:internal/process/task_queues:95:5
  
  - worker.js:77 async worker
    [webpack]/[image-minimizer-webpack-plugin]/dist/worker.js:77:25
  
  - index.js:327 
    [webpack]/[image-minimizer-webpack-plugin]/dist/index.js:327:18
  
  - child-compiler.js:169 
    [webpack]/[html-webpack-plugin]/lib/child-compiler.js:169:18
  
  - Compiler.js:551 finalCallback
    [webpack]/[webpack]/lib/Compiler.js:551:5
  
  - Compiler.js:577 
    [webpack]/[webpack]/lib/Compiler.js:577:11
  
  - Compiler.js:1200 
    [webpack]/[webpack]/lib/Compiler.js:1200:17
  
  
  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [webpack]/[tapable]/lib/Hook.js:18:14
  
  - Compiler.js:1196 
    [webpack]/[webpack]/lib/Compiler.js:1196:33
  
  - Compilation.js:2795 finalCallback
    [webpack]/[webpack]/lib/Compilation.js:2795:11
  
  - Compilation.js:3100 
    [webpack]/[webpack]/lib/Compilation.js:3100:11
  
  
  - Hook.js:18 Hook.CALL_ASYNC_DELEGATE [as _callAsync]
    [webpack]/[tapable]/lib/Hook.js:18:14
  
  - Compilation.js:3093 
    [webpack]/[webpack]/lib/Compilation.js:3093:38
  
  
  - task_queues:95 process.processTicksAndRejections
    node:internal/process/task_queues:95:5
  


2 ERRORS in child compilations (Use 'stats.children: true' resp. '--stats-children' for more details)
webpack 5.88.2 compiled with 4 errors in 1174 ms
error: script "build" exited with code 1 (SIGHUP)

mozjpeg/vender/cjpeg 가 없다는 오류를 낸다 (ENOENT)

attempt 02. 스크립트 작성 후 bun 에서 바로 실행하기


지금 상황에서는 ImageMinimizerPlugin이 문제가 되는지, imagemin이 문제가 되는지, mozjpeg가 문제가 되는지 모르기 때문에, root에 imagemin만 실행 가능하게 해서 ImageMinimizerPlugin을 배제 한 뒤에 오류 트래킹을 할 예정이다.

파일 생성
touch imageMinimizer.ts

이번에도 imagemin을 사용할 예정이므로, imagemin readme을 참고한다.

import imagemin from 'imagemin';
import imageminJpegtran from 'imagemin-jpegtran';
import imageminPngquant from 'imagemin-pngquant';

const files = await imagemin(['images/*.{jpg,png}'], {
	destination: 'build/images',
	plugins: [
		imageminJpegtran(),
		imageminPngquant({
			quality: [0.6, 0.8]
		})
	]
});

console.log(files);

패키지 설치
bun add -D @types/imagemin imagemin-jpegtran @types/imagemin-jpegtran imagemin-pngquant @types/imagemin-pngquant

현재 images 폴더가 있으므로, 바로 bun imageMinimizer.ts를 실행 해 주면,

TypeError: Error occurred when handling file: images/*.{jpg,png}

TypeError: Executable not found in $PATH: "node_modules/jpegtran-bin/vendor/jpegtran"
    at spawn (native)
    at spawn (node:child_process:610:8)
    at <anonymous> (node:child_process:2:21)
    at <anonymous> (/Users/joepasss/joepasss/webpack/node_modules/exec-buffer/node_modules/execa/index.js:139:3)
    at <anonymous> (/Users/joepasss/joepasss/webpack/node_modules/exec-buffer/index.js:37:44)
    at processTicksAndRejections (:55:39)
 code: "ERR_INVALID_ARG_TYPE"

      at node:child_process:611:8

비슷하게 {특정 패키지}/vender/~ 가 뜨는데, 이게 imagemin 문제인지 확인하기 위해 plugins를 비워놓고 실행

import imagemin from "imagemin";
import imageminJpegtran from "imagemin-jpegtran";
import imageminPngquant from "imagemin-pngquant";

const files = await imagemin(["images/*.{jpg,png}"], {
  destination: "build/images",
  plugins: [],
});

console.log(files);

이후 bun imageMinimizer.ts를 실행해 보면

[
  {
    data: Buffer(1341775) [ 255, 216, 255, 224, 0, 16, 74, 70, 73, 70, 0, 1, 1, 1, 0, 72, 0, 72, 0, 0, 255, 226, 12, 88, 73, 67, 67, 95, 80, 82, 79, 70, 73, 76, 69, 0, 1, 1, 0, 0, 12, 72, 76, 105, 110, 111, 2, 16, 0, 0, 109, 110, 116, 114, 82, 71, 66, 32, 88, 89, 90, 32, 7, 206, 0, 2, 0, 9, 0, 6, 0, 49, 0, 0, 97, 99, 115, 112, 77, 83, 70, 84, 0, 0, 0, 0, 73, 69, 67, 32, 115, 82, 71, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 246, 214, 0, 1, 0, 0, 0, 0, 211, 45, 72, 80, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 99, 112, 114, 116, 0, 0, 1, 80, 0, 0, 0, 51, 100, 101, 115, 99, 0, 0, 1, 132, 0, 0, 0, 108, 119, 116, 112, 116, 0, 0, 1, 240, 0, 0, 0, 20, 98, 107, 112, 116, 0, 0, 2, 4, 0, 0, 0, 20, 114, 88, 89, 90, 0, 0, 2, 24, 0, 0, 0, 20, 103, 88, 89, 90, 0, 0, 2, 44, 0, 0, 0, 20, 98, 88, 89, 90, 0, 0, 2, 64, 0, 0, 0, 20, 100, 109, 110, 100, 0, 0, 2, 84, 0, 0, 0, 112, 100, 109, 100, 100, 0, 0, 2, 196, 0, 0, 0, 136, 118, 117, 101, 100, 0, 0, 3, 76, 0, 0, 0, 134, 118, 105, 101, 119, 0, 0, 3, 212, 0, 0, 0, 36, 108, 117, 109, 105, 0, 0, 3, 248, 0, 0, 0, 20, 109, 101, 97, 115, 0, 0, 4, 12, 0, 0, 0, 36, 116, 101, 99, 104, 0, 0, 4, 48, 0, 0, 0, 12, 114, 84, 82, 67, 0, 0, 4, 60, 0, 0, 8, 12, 103, 84, 82, 67, 0, 0, 4, 60, 0, 0, 8, 12, 98, 84, 82, 67, 0, 0, 4, 60, 0, 0, 8, 12, 116, 101, 120, 116, 0, 0, 0, 0, 67, 111, 112, 121, 114, 105, 103, 104, 116, 32, 40, 99, 41, 32, 49, 57, 57, 56, 32, 72, 101, 119, 108, 101, 116, 116, 45, 80, 97, 99, 107, 97, 114, 100, 32, 67, 111, 109, 112, 97, 110, 121, 0, 0, 100, 101, 115, 99, 0, 0, 0, 0, 0, 0, 0, 18, 115, 82, 71, 66, 32, 73, 69, 67, 54, 49, 57, 54, 54, 45, 50, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 115, 82, 71, 66, 32, 73, 69, 67, 54, 49, 57, 54, 54, 45, 50, 46, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... 1341262 more ],
    sourcePath: "images/header-image.jpg",
    destinationPath: "build/images/header-image.jpg"
  }, {
    data: Buffer(404) [ 137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 50, 0, 0, 0, 50, 8, 6, 0, 0, 0, 30, 63, 136, 177, 0, 0, 0, 1, 115, 82, 71, 66, 0, 174, 206, 28, 233, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 14, 195, 0, 0, 14, 195, 1, 199, 111, 168, 100, 0, 0, 1, 41, 73, 68, 65, 84, 104, 67, 237, 217, 61, 10, 194, 64, 16, 134, 225, 120, 0, 91, 237, 245, 36, 30, 66, 143, 99, 105, 43, 158, 201, 51, 216, 122, 11, 59, 65, 103, 212, 15, 150, 16, 66, 118, 179, 59, 63, 50, 47, 124, 168, 169, 124, 208, 77, 147, 46, 138, 162, 232, 111, 90, 208, 142, 180, 245, 231, 147, 110, 123, 218, 238, 251, 54, 63, 70, 188, 104, 55, 154, 38, 230, 64, 123, 210, 30, 180, 45, 95, 200, 141, 191, 60, 35, 52, 49, 64, 240, 119, 56, 241, 133, 210, 52, 49, 213, 16, 72, 3, 83, 29, 129, 36, 49, 205, 16, 72, 2, 211, 28, 129, 90, 98, 196, 16, 168, 5, 70, 28, 129, 106, 98, 212, 16, 168, 6, 70, 29, 129, 230, 96, 204, 32, 80, 9, 198, 28, 2, 229, 96, 204, 34, 208, 20, 140, 121, 4, 26, 195, 184, 65, 160, 33, 140, 59, 4, 74, 49, 119, 154, 75, 4, 98, 12, 35, 24, 192, 187, 208, 92, 150, 254, 157, 120, 253, 51, 227, 162, 20, 113, 166, 245, 207, 140, 139, 134, 14, 118, 122, 102, 92, 96, 198, 238, 78, 110, 48, 83, 110, 177, 230, 49, 83, 16, 200, 44, 38, 7, 129, 204, 97, 74, 16, 200, 12, 102, 14, 2, 169, 99, 106, 32, 144, 26, 166, 38, 2, 137, 99, 90, 32, 144, 24, 166, 37, 2, 53, 199, 72, 32, 80, 51, 140, 36, 2, 85, 199, 104, 32, 80, 53, 140, 38, 2, 245, 49, 43, 90, 118, 252, 204, 142, 31, 119, 105, 33, 16, 48, 87, 218, 146, 47, 148, 180, 249, 189, 106, 199, 191, 68, 49, 34, 138, 162, 200, 90, 93, 247, 6, 139, 252, 198, 202, 131, 239, 188, 39, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 ],
    sourcePath: "images/delete.png",
    destinationPath: "build/images/delete.png"
  }
]

잘 되는 걸 볼 수 있다.

결론.


plugin으로 implement 하든, 웹팩 밖에서 implement 하든 imagemin 플러그인이 node_module 상에서 특정 imagemin 플러그인의 vender 폴더가 비어있다고 오류가 나는데, 웹팩이나 imagemin의 오류가 아닌, bun이 패키지를 설치하는 방법이 npm 또는 yarn과 다르기 때문에 특정 파일이 설치되지 않았던 것 같다.

실제로 yarn으로 바꾸고 실행해 보니 잘 되는것을 보아 하니, bun.build를 직접 사용하는 것이 아니라 webpack, imagemin 등의 특정 npm package를 사용해 프로젝트를 빌드하는 것은 노드를 사용하는것에 비해 메리트가 떨어져보인다.

bun이 충분히 성숙하기 전 까지는 node + yarn 조합을 사용해야겠다

전체 코드 보기

0개의 댓글