20280826 학습내용 - webpack, vite, 브라우저 버전

작성일

“빌드 도구를 바꿨을 뿐인데” — 번들러 마이그레이션이 브라우저 지원 정책까지 바꾼 이야기라는 글을 읽었다.

웹팩이 느려서 Vite(와 그 내부의 rolldown)으로 바꾼 거랑 그 여파를 설명한 글임

웹팩 vs Vite #

웹팩이 느린 건 유명하다. 근데 왜 느릴까?

웹팩은 번들러다. dev 서버든 빌드든 실행하면 우선 번들링을 실행한다. 이때 index.js 등 미리 정의해 둔 진입점(여러 개일 수도 있음)에서 시작해 의존성 그래프를 만들고 몇 개의 번들로 묶는다. 그래프를 만들 때 import/require/css import 등까지 처리한다. css등은 loader가 따로 처리한다. 실제로 웹팩 설정을 해보면 css를 위한 로더를 따로 설정해 줘야 할 때가 있다.

그런데 파일이 늘어나면 이런 방식은 개발 시 특히 느려진다. 개발 서버 시작 전에 미리 처리를 전부 해놓아야 하고 수정시마다 HMR(핫 모듈 리로딩)과정에서 의존성 그래프가 다시 그려지기 때문이다. 따라서 Next 내부의 turbopack이나 rust 기반 rspack 등이 나옴.

이 상황에서 vite와 그 밑에 있는 esbuild/rollup(지금은 rolldown으로 통합되었지만) 계열이 엄청나게 빠른 DX로 주목받았다. 서버를 먼저 띄운 뒤 브라우저에서 요청하는 모듈만 그때그때 변환해 내려주어서 이런 게 가능했다. ES6에서 ESM 모듈이 등장하면서 이제 브라우저가 import를 따라갈 수 있어져서 이런 걸 할 수 있게 된 것이다. 웹팩은 cjs 시절부터 나온 도구여서 하위 호환성 등을 생각하면 이런 게 불가능. 그리고 esbuild는 golang이라 빠른 것도 있다.

그러니까 일단 개발 서버를 시작하고 브라우저가 특정 페이지/파일을 요청하면 그때그때 그 파일과 거기 있는 의존성을 읽어서 내려주는 것이다. 근데 그러면 node_modules에 있는 라이브러리 등은 요청이 폭발한다. 따라서 이런 걸 한다.

여기에 golang의 성능까지 더해져 빠른 것이다.

HMR 또한, esm을 사용하는 vite가 훨씬 빠르게 가능하다. 딱 변경된 파일 + 그게 영향을 미치는 경계 까지만 invalidate하면 되기 때문이다.

반면 vite에서는 프로덕션 빌드에서는 좀 더 트리셰이킹 등의 최적화를 잘하는 번들러인 rollup를 사용했었다. 지금은 역시 rolldown

위 글에서 발생했다는 문제 #

DX를 위해 vite로 마이그레이션했다고 한다. 몇몇 웹팩 플러그인이나 import 경로 등을 수정했다고. 근데 프로덕션 배포하니 오류 발생

폴리필 문제였는데, 웹팩에서 지원하던 폴리필과 달리 vite에서 사용했던 폴리필이 Array.prototype.findLast()를 지원하지 않아서 오류가 발생하고 있었다고 한다. 해당 메서드를 vite가 쓰던 폴리필에서 지원을 안 해서, 해당 메서드를 지원하지 않는 브라우저에서 typeError가 발생하고 있었다.

물론 다 핫픽스를 하거나 다른 폴리필 쓸 수 있지만, 근본 원인은 구형 브라우저 사용임. 따라서 es2022까지만 사용하게 하고 그 이상은 금지. 그리고 구형 브라우저에는 https://browser-update.org/ 를 활용해 업그레이드 배너를 노출했다고 한다. + 매년 사용자 데이터 기반으로 지원 범위 재검토 컨벤션 정립(https://blog.lemonbase.team/레몬베이스가-폴리필을-대하는-방법-8c9f8c8bddc4) 저 글에서는 eu, 마이크로소프트 팀즈 등 여러 제품에서 브라우저 지원 범위를 어떻게 정했는지 좀 더 나옴.

.browserslistrc로 지원 대상 브라우저를 명시하고 eslint-plugin-compat이라는 플러그인으로 지원 범위 밖의 js 문법은 린터가 잡도록 했다고 한다. 이렇게 하면 구조적으로 es2023등 컨벤션을 벗어나는 js API를 쓰는 게 막힌다.

그리고 구버전 브라우저 테스트는 생각보다 어려우니(browserstack 등을 써도) 지원 범위를 넓게 가져가면 테스트 비용이 늘어난다는 걸 고려하자.

또한 폴리필을 맹신하지 말고, 프로젝트에서 사용하는 API가 폴리필에서 다 잘 지원되는지 확인하라는 교훈

browserlist #

Browserslist와 함께 기준 사용 https://web.dev/articles/use-baseline-with-browserslist?hl=ko

browserlist는 package.json이나 .browserslistrc에 쓰여서, 해당 프로젝트에서 지원하는 최소 브라우저 목록을 명시한다.