번들러
Bundler
도구
흩어진 화면 쪽 파일을 서로의 의존 관계대로 엮어 브라우저가 받기 좋은 몇 덩어리로 묶어 주는 도구입니다.
등장 배경
웹 화면을 만들던 초기에는 파일을 브라우저에 하나씩 알려 줬습니다. 문서 맨 아래에 스크립트를 부르는 줄을 적어 두면 브라우저가 그 줄을 하나씩 읽어 파일을 받아 왔습니다. 파일이 다섯 개일 때는 아무 문제가 없었습니다.
화면이 커지면서 그 줄이 예순 개가 됐고, 그때부터 순서가 발목을 잡았습니다. 아래쪽 파일이 위쪽 파일에서 만든 값을 쓰고 있어서 순서를 한 칸만 바꿔도 화면이 하얗게 떴습니다. 이름이 겹치는 사고도 잦았습니다. 서로 다른 파일에서 같은 이름을 쓰면 나중에 읽힌 쪽이 앞의 것을 덮어썼는데, 누가 누구를 덮었는지는 화면이 깨진 뒤에야 알았습니다. 새로 온 사람이 줄을 하나 옮기고 "이거 왜 깨지죠" 하고 묻는 장면이 반복됐습니다.
속도도 문제였습니다. 파일 하나마다 브라우저가 서버에 따로 물어봐야 했으니, 예순 개면 예순 번을 오갔습니다. 파일 내용은 짧은데 오가는 시간이 더 걸리는 상황이 벌어졌습니다.
번들러는 이 일을 사람 대신 기계가 하게 만든 도구입니다. 파일마다 무엇을 필요로 하는지 적어 두면, 번들러가 그 관계를 읽어 순서를 스스로 정하고 필요한 것만 모아 몇 덩어리로 묶어 줍니다. 순서를 사람이 관리하던 자리가 사라진 것이 이 도구가 바꾼 가장 큰 부분입니다.
해결하는 문제
번들러가 푸는 문제는 네 가지입니다. 하나씩 보면 서로 다른 일처럼 보이지만 전부 같은 작업의 부산물입니다.
- 의존 관계 정리. 각 파일이 어떤 파일을 필요로 하는지 읽어 나가며 관계를 그리고, 그 관계대로 순서를 정합니다. 사람이 스크립트 줄의 순서를 관리할 일이 없어집니다.
- 요청 수 줄이기. 파일 1,200개를 서너 덩어리로 합쳐 내보내면 브라우저가 오가는 횟수가 그만큼 줄어듭니다. 첫 화면이 뜨는 시간에서 이 부분이 눈에 띄게 줄어듭니다.
- 브라우저가 모르는 것 옮기기. 브라우저는 자바스크립트만 알고 타입스크립트나 그 밖의 문법은 모릅니다. 번들러가 중간에서 브라우저가 아는 형태로 바꿔 줍니다. 스타일 파일이나 이미지를 코드에서 불러 쓰는 것도 이 단계를 거칩니다.
- 결과물 줄이기. 공백과 주석을 걷어 내고 변수 이름을 짧게 바꿉니다. 여기에 쓰지 않는 코드를 아예 빼는 트리 셰이킹까지 걸면 2.4메가바이트짜리 결과물이 380킬로바이트로 내려가기도 합니다.
묶는 단위는 하나가 아닙니다. 모든 화면에서 쓰는 코드는 한 덩어리로 두고 특정 화면에서만 쓰는 코드는 따로 떼는데, 이렇게 나누는 것이 코드 스플리팅입니다. 떼어 둔 덩어리는 그 화면에 들어갈 때 받습니다.
덩어리 이름에는 내용에서 뽑은 문자열을 붙입니다. 내용이 그대로면 이름도 그대로라 브라우저가 지난번에 받아 둔 것을 다시 씁니다. 반대로 한 글자라도 바뀌면 이름이 달라져 새로 받습니다. 배포할 때마다 전부 새로 받게 하지 않으려고 쓰는 방식입니다.
대안
대안은 크게 셋입니다. 다만 셋 다 번들러를 없애는 쪽이 아니라 덜 쓰거나 안 보이게 하는 쪽에 가깝습니다.
- 브라우저가 직접 모듈을 읽게 두는 방법입니다. 요즘 브라우저는 파일끼리의 의존 관계를 스스로 읽을 수 있어서, 묶지 않고 그대로 내보내도 화면이 뜹니다. 개발할 때는 편하지만 운영에 그대로 내보내면 파일이 파일을 부르고 그 파일이 또 다른 파일을 부르는 모양이 되어, 첫 화면까지 오가는 횟수가 오히려 늘어납니다.
- 개발 중에는 묶지 않고 운영 빌드에서만 묶는 방법입니다. 화면을 고치는 동안에는 브라우저가 요청한 파일만 그때그때 바꿔 내려 주고, 실제로 내보낼 때만 전부 묶습니다. 최근 도구들이 기본으로 삼는 방식이고, 고친 내용이 화면에 반영되는 시간이 짧아집니다.
- 라이브러리를 CDN에서 바로 가져다 쓰는 방법입니다. CDN은 자원을 사용자와 가까운 거점에서 내려 주는 배포망인데, 자주 쓰는 라이브러리를 거기서 받으면 우리 결과물에 넣지 않아도 됩니다. 대신 버전을 우리가 잠글 수 없고 그쪽이 멈추면 우리 화면도 멈춥니다.
현실에서 가장 흔한 선택은 셋 중 어느 것도 아닙니다. 프레임워크가 번들러를 안에 품고 있어서 쓰는 사람이 설정 파일을 열어 볼 일이 없는 경우입니다. 이때도 묶는 일 자체는 그대로 일어납니다. 결과물 크기가 문제가 되는 순간에는 결국 그 아래를 들여다보게 됩니다.
실무 용례
"번들 사이즈가 1.8메가로 늘었어요. 뭐가 들어왔는지 보고 계신가요?"
결과물이 커져 첫 화면이 느려졌으니 무엇이 새로 들어왔는지 찾아보자는 뜻입니다.
"그 라이브러리 통째로 불러오지 말고 쓰는 함수만 가져오세요."
불러오는 방식에 따라 안 쓰는 코드까지 결과물에 실린다는 지적입니다.
"번들러 설정 건드린 사람 있어요? 빌드가 3분에서 9분이 됐는데요."
묶는 규칙을 바꾸면 빌드 시간이 그대로 영향을 받는다는 말입니다.
페이지덱에서 이 말이 나온 자리는 첫 화면 속도 이야기였습니다. 민서가 문서 편집 화면에 글꼴 미리보기를 붙이면서 폰트 관련 라이브러리를 통째로 불러왔고, 다음 배포에서 결과물이 900킬로바이트에서 1.8메가바이트로 늘었습니다.
태오가 번들러가 뽑아 주는 구성 보고서를 열어 어느 덩어리가 커졌는지 짚었습니다. 고친 방법은 두 가지였습니다. 라이브러리에서 실제로 쓰는 함수 두 개만 불러오게 바꾸고, 미리보기 화면 코드를 따로 떼어 그 화면에 들어갈 때만 받게 했습니다. 결과물은 1.0메가바이트로 내려왔습니다.
흔한 오해
번들러가 코드를 빠르게 만들어 준다고 읽는 경우가 가장 많습니다. 결과물이 작아지고 화면이 빨리 뜨니 그렇게 보입니다. 하지만 줄어든 것은 코드를 받아 오는 시간이지 실행하는 시간이 아닙니다. 목록 만 건을 한 번에 그리느라 멈추는 화면은 번들을 반으로 줄여도 그대로 멈춥니다. 여기를 헷갈리면 느린 원인을 엉뚱한 곳에서 찾느라 며칠을 씁니다.
하나로 크게 합칠수록 좋다고 보는 것도 흔한 오해입니다. 요청 수를 줄이는 것이 목적이었으니 자연스러운 생각입니다. 그런데 전부 한 덩어리로 묶으면 첫 화면에 필요 없는 코드까지 처음에 다 받게 됩니다. 관리자 화면에서만 쓰는 코드를 로그인 화면에서 받는 식입니다. 게다가 한 줄만 고쳐도 덩어리 전체의 이름이 바뀌어 사용자가 매번 전부 새로 받습니다.
같이 보면 좋은 페이지
마지막 업데이트 2026-09-16