☘️ esbuild js build for blog

그간 자바스크립트를 이 Hugo으로 생성하는 블로그에 사용하면서, 여기저기 그냥 <script>-태그를 써왔었다. 한군데로 정리하기도 뭐하고, 자바스크립트를 쓰는 기능은 메인이 아니라고 생각해와서.

검색, darkmode만 자바스크립트를 사용하고 조금씩 붙여놓은 easter eggs도 사용하니까 조금씩 늘어난 것 같다.

그냥 cdnjs 같은걸 써도 되겠지만, 그냥 패키지로 내려받아서 아예 내 블로그에 올리는게 남에 cdn bandwidth을 줄여주는 도리인 것 같았다…만 github cdn의 bandwidth은 여전히 사용하는 것. 😜

여튼, 그렇다고 사용하는 의존성(예: jquery)의 크기를 줄여서 내보낸 것도 아니고 점점 의존성관계가 복잡해지는거 같아서 정리를 시작해봤다.

(아참!) CSS은 Hugo / SCSS 컴파일으로 관리하고 있다

즉, 다른 일반적인 웹앱 프로젝트와 달리 별도의 이미지 에셋이나 CSS관련 빌드를 신경 쓸 필요가 없다는 뜻. 이하의 내용들도 그걸 염두에 두고 고려했다.

🥡 첫 시도: deno bundle

최초 시도는 그냥 deno bundle-기능을 사용하는 것: 👉 https://docs.deno.com/runtime/reference/bundling/

  1. [장점👍] 그냥 mise 같은걸로 deno만 설치하고 바로 적용가능.
  2. [장점👍] watcher-mode 지원한다.

    • 입력파일, 의존성이 변경되면 자동으로 rebuild해줘서 개발할 때 편리하다.
  3. [장점👍] 적당히 빠르다 + minification도 잘 지원한다.

    • 찾아보니까, tree-shaking도 해주고 할건 다 하는 느낌이었다.
    • minified : 570KB => 280KB 정도로 줄여줌.
  4. [단점👎] 하나의 output만 지원가능.

    • …어차피 하나의 bundle.js-만 생성하는데 사용하고 있지만😅

장점으로는, 확실히 로딩자체가 더 가벼워진 느낌적 느낌이 들어서 쾌적했다.

그러나 문득 이걸로 만족해도 되겠는가 하는 강박이 들었다.

苦
Dukkha!

그래서 요즘 누구나🐕🐮 사용한다는 Vite을 시도해봤다.

😰 실패: npm + vite

다른 웹애플리케이션 프로젝트에선 개인적으로나 일터에서 조금씩 써왔지만, 막상 적용하고 나니까… 후회스러웠다.

(장점은 적지 않겠다: 어차피 지원할거 다 지원하니까)

단점은:

  1. 의도하지 않은 html/image 에셋들도 번들링한다고 난리였다.

    • 오히려 그러지 않도록 뜯어 말리는 설정이 너무 컸다. ㅋㅋㅋ
  2. node.js package.json type=module|cjs 광란의 블루스가 다시 살아났다.
  3. 어차피 live-reload 같은 "vite server"-에서 기대하는 기능들, "hugo server"-이 이미 제공하고 있어서 있어도 무의미했다.
traum!
XXXXXX, XXXXXX never change...

굳이 내 개인블로깅을 하는데, vite 같은 누구나 쓰지만, 남들이 쓴다니까 옆사람이 써서 나도 써야 하는… 그 기술이 꼭 그자체로 나쁜건 아니지만, 그런 상황과 순환은… 굳이 …괜찮았다. 🙂‍↔️1

‍🔥 재시도: deno run npm:esbuild

그래서 그냥 deno에서 esbuild 실행하는걸로 바꿈: …하지만, deno import와 node_modules/-에 위치하기를 기대하는 esbuild와의 차이로 제대로 동작하지 않았다. 😥

그래서 그냥 npx/npm으로 재시도.

🐦‍🔥 최종판: npm + esbuild

  1. [장점👍] 빠르다

    • esbuild 자체가 가벼워서 좋은거 같다.
    • 다른 parcel, vite보다 가벼울거 같다.
  2. [장점👍] 다수 입력=>출력 설정 쉽다.
  3. [장점👍] deno-bundle보다 용량도 준거 같다: 280KB => 200KB
  4. [단점👎] 모르겠다.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  # Makefile

  NPX ?=npx

  ESBUILD_ADDOPTS ?=

  bundle-js:
  	-$(MKDIR) -pv ./static/js

  	$(NPX) esbuild --bundle --minify --target=chrome58,firefox57,safari11,edge16 $(ESBUILD_ADDOPTS) \
  		./js/bundle.mjs --outfile=./static/js/bundle.js

https://esbuild.github.io/getting-started/#bundling-for-the-browser 참고해서 베껴왔다.

🎁 보너스: Makefile-와 npx concurrently

그리고 추가적으로 Makefile-에서 hugo 서버를 시작할 때에, 동시에 "esbuild watcher"-도 concurrently-을 이용해서 실행하도록 추가했다.

1
2
3
4
5
6
7
8
  # Makefile
  # ...생략

  watch-bundle-js:
  	ESBUILD_ADDOPTS=--watch $(MAKE) bundle-js

  serve:
  	$(NPX) concurrently 'hugo server' "$(MAKE) watch-bundle-js"

Footnotes


1

(그리고 더 골때린건 그걸 써야한다고 옹호하는 emotionally attached한 사람은, 아는 node.js/typescript 잘한다는 형이/웹사이트가/어디어디서 그렇다고 "카더라"라고 해서… XXX/YYY이 나빠잉,한다고 카더라 해서…라는게 이유인 경우라면… 더 안습)