← 모두의 툴

정규식 기반 HTML 압축기가 실패하는 지점 — pre·textarea 공백 붕괴

가이드 · 2026-08-19 최종 확인

HTML을 압축(minify)한다는 건 결국 "의미 없는 공백을 지운다"는 뜻입니다. 그런데 문제는 HTML에서 "의미 없는 공백"과 "의미 있는 공백"을 구분하려면 태그를 이해해야 한다는 점입니다. 이 가이드는 정규식만으로 동작하는 압축기가 왜 이 구분을 못 하는지, 그리고 그게 실제로 어떤 화면 깨짐으로 이어지는지 설명합니다.

1. 진짜 파서 vs 정규식 치환

HTML을 제대로 압축하려면 원래는 문서를 파싱해서 각 태그가 "일반 요소"인지 "raw text 요소"(내용을 있는 그대로 취급해야 하는 태그)인지 구분해야 합니다. 하지만 이 도구는 DOM 트리를 전혀 만들지 않습니다. 대신 입력된 텍스트 전체에 정규식을 순서대로 적용합니다: 주석 제거(<!--...--> 패턴 삭제), 줄바꿈 제거(모든 개행을 공백 하나로), 태그 간 공백 제거(> <><), 속성 공백 정규화(연속 공백 2칸 이상 → 1칸). 이 네 단계 어디에도 "지금 이 위치가 pre 태그 안인가"를 확인하는 로직이 없습니다. 정규식은 문자열만 보지, 그 문자열이 어떤 태그 안에 있는지는 전혀 모릅니다.

2. 왜 pre·textarea에서 문제가 되나

<pre> 태그는 HTML 명세상 "화이트스페이스를 그대로 보존해서 렌더링하라"는 지시입니다. 코드 블록을 표시할 때 들여쓰기·줄바꿈이 그대로 유지되어야 하는 이유가 이것입니다. <textarea>도 마찬가지로 내부 텍스트가 그 입력 필드의 기본값으로 그대로 쓰이며, 줄바꿈과 연속 공백이 실제 값의 일부입니다. 그런데 이 압축기의 "줄바꿈 제거" 옵션은 문서 전체의 개행을 공백으로 바꾸고, "속성 공백 정규화"는 연속 공백을 한 칸으로 줄이는데, 둘 다 지금이 pre/textarea 안인지 밖인지 구분하지 않고 문서 전체에 똑같이 적용됩니다. 결과적으로 코드 블록의 들여쓰기가 전부 한 줄로 뭉개지거나, textarea의 초기값에 있던 개행이 사라집니다.

예시:
<pre>
function add(a, b) {
    return a + b;
}
</pre>
"줄바꿈 제거"를 켜면 이 코드 블록은 function add(a, b) { return a + b; } 처럼 한 줄로 뭉개져서, 화면에는 들여쓰기도 줄 구분도 없는 코드가 그대로 표시됩니다. 사람이 읽던 코드 스니펫이 압축 한 번에 못 알아보게 변합니다.

3. 실제 파서 기반 압축기는 어떻게 다른가

html-minifier-terser 같은 실제 프로덕션용 라이브러리는 HTML을 진짜로 토큰화·파싱해서, 각 요소가 "raw text 요소"(pre, textarea, script, style 등)인지 판단한 뒤 그 안에서는 공백 압축 로직을 아예 건너뜁니다. 게다가 script·style 내부는 별도로 JS/CSS 문법을 이해하는 압축기(terser, cssnano 등)에 넘겨 안전하게 압축합니다. 이 사이트의 도구는 그 반대로, script·style 내부 코드도 HTML 전체와 동일한 정규식으로 처리하기 때문에 문법적으로 안전한 압축이 아닙니다 — 그래서 도구 자체 FAQ에서도 JS는 javascript-minifier, CSS는 css-minifier를 따로 쓰라고 안내하고 있습니다.

4. IE 조건부 주석 같은 다른 함정

공백뿐 아니라 주석 제거도 같은 구조적 한계를 가집니다. <!--[if IE]>...<![endif]--> 같은 IE 조건부 주석은 문법적으로는 HTML 주석이지만 실제로 브라우저 동작에 영향을 주는 코드입니다. 이 도구의 주석 제거 정규식은 일반 주석과 조건부 주석을 구분하지 못하므로, 그런 코드가 있는 파일은 주석 제거 옵션 자체를 꺼야 안전합니다.

5. 실무에서 이 도구를 안전하게 쓰는 법

자주 묻는 질문

Q. 이 압축기는 실제 HTML 파서를 쓰나요?

A. 아니요. DOM 트리를 만들어 태그 구조를 이해하는 방식이 아니라, 정규식으로 텍스트를 순서대로 치환하는 방식입니다. 그래서 빠르지만 pre/textarea/조건부 주석처럼 문맥이 중요한 경우를 구분하지 못합니다.

Q. pre 태그 안 코드가 압축 후 왜 한 줄로 붙나요?

A. "줄바꿈 제거"와 "속성 공백 정규화" 옵션이 문서 전체의 개행·연속 공백을 태그 구분 없이 똑같이 처리하기 때문입니다. pre 태그 안은 원래 공백이 보존돼야 하는데 이 도구는 그 예외를 두지 않습니다.

Q. script·style 태그 내부도 이 도구로 안전하게 압축되나요?

A. 문법에 맞는 안전한 압축(변수명 유지, 세미콜론 자동 삽입 등)은 하지 않습니다. HTML 전체를 하나의 텍스트로 취급해 개행·공백만 정리하므로, 실제 JS/CSS 압축이 필요하면 javascript-minifier·css-minifier를 별도로 쓰는 게 안전합니다.

Q. 그럼 이 도구는 언제 쓰면 되나요?

A. pre/textarea가 없고 조건부 주석 같은 특수 코드가 없는 일반적인 HTML을 빠르게 한 번 압축해볼 때는 충분합니다. 코드 스니펫이 들어간 페이지나 자동화된 빌드 파이프라인에는 파서 기반 라이브러리를 쓰는 게 안전합니다.