Herb: HTML-aware ERB 파서 및 툴링 생태계
발표자는 기존 Stimulus 개발 시 컨트롤러 이름 오타와 같은 사소한 실수에도 아무런 피드백이 없어 디버깅에 어려움을 겪었던 경험을 공유하며, 이를 해결하기 위해 새로운 접근 방식이 필요하다고 강조했습니다. 기존 Stimulus LSP는 HTML만 지원하고 ERB나 태그 헬퍼에는 적용되지 않는 한계가 있었으며, Ruby LSP의 ERB 지원 프로토타입 또한 강력한 기능을 제공하기에는 부족했습니다. 이에 대한 해결책으로 HTML 구조를 인식하는 새로운 ERB 파서인 Herb가 개발되었습니다.
Herb의 핵심 기능
Herb는 단순히 파서를 넘어 광범위한 툴링 생태계를 제공합니다. C 언어로 개발되어 높은 이식성을 가지며(Node, Ruby, 브라우저에서 WebAssembly를 통해 실행 가능), 다음과 같은 기능을 포함합니다:
- 언어 서버 (Language Server)
- 별도의 설정 없이 즉시 사용 가능합니다.
- VS Code, Cursor, Zed, Neovim 등 주요 에디터를 지원합니다.
- 닫는 태그 누락, 구문 오류, ERB 태그 내 Ruby 코드 오류 등 즉각적인 피드백을 제공하여 개발 중 실시간으로 문제를 인지하고 수정할 수 있도록 돕습니다.
- 린터 (Linter)
- 뷰 코드 작성에 대한 모범 사례를 안내하고 일반적인 실수를 방지합니다.
- 스타일 일관성을 강제하고 접근성 규칙 준수를 유도합니다.
- 현재 50개 이상의 린트 규칙을 제공하며, 잠재적인 중복 ID 감지 등 파일 전체의 제어 흐름을 이해합니다.
- 진단 메시지에서 문서 링크를 제공하여 오류의 원인과 해결 방법을 쉽게 이해할 수 있도록 돕습니다.
- 포맷터 (Formatter)
- 어떤 형태의 HTML ERB 코드라도 일관되고 아름답게 자동 포맷팅합니다.
- 들여쓰기 및 구조적 문제를 자동으로 해결하며, Tailwind CSS 클래스 정렬 기능도 내장되어 있습니다.
- CLI 및 에디터 저장 시 자동 포맷팅을 지원합니다.
- 린트 위반 사항을 자동으로 수정하는
dash-test-fix명령어를 제공합니다.
Herb 엔진: HTML-aware 렌더링
Herb는 템플릿의 내부 구조를 파악하는 능력을 바탕으로 렌더링 엔진을 혁신했습니다. 이는 ERB 엔진 API와 호환되며, 다음과 같은 향상된 기능을 제공합니다.
-
향상된 오류 메시지: 브라우저에서 템플릿 오류 발생 시, 에디터에서와 동일하게 정확한 라인과 컬럼 정보를 포함한 상세한 오류 페이지를 제공합니다.
-
개발 디버그 속성: 개발 환경에서 렌더링된 HTML에 파일명, 타입(컴포넌트, 부분 템플릿, 뷰), 상대 경로, 전체 경로 등 디버그 속성을 자동으로 주입합니다. 이를 통해 브라우저에서 뷰 파일의 시각적 윤곽선을 확인하고, 클릭 시 해당 파일의 에디터 특정 라인으로 바로 이동할 수 있습니다.
-
디버그 메뉴: ERB 윤곽선 토글, 태그 호버 시 렌더링에 사용된 ERB 부분 표시 등 편리한 디버깅 기능을 제공합니다.
Reaction View: Action View의 미래 재구상
Reaction View는 Herb 엔진을 Rails 애플리케이션에 통합하여 Action View의 기능을 확장하고 재구상하려는 이니셔티브입니다. 현재 Herb 엔진의 모든 디버깅 및 향상된 오류 메시지 기능을 Rails에서 바로 사용할 수 있도록 지원합니다.
Reaction View의 미래 비전
-
Action View 최적화: 렌더링 성능 향상, 부분 템플릿 인라인화, 불필요한 공백 최소화 등을 통해 뷰 레이어의 효율성을 높입니다.
-
반응형 템플릿: Phoenix LiveView나 Stimulus Reflex와 같은 라이브러리의 아이디어를 차용하여 Rails에 반응형 기능을 도입합니다.
-
클라이언트 측 렌더링: 제한된 ERB를 웹 컴포넌트나 React 컴포넌트로 트랜스파일하여 클라이언트 측 렌더링을 가능하게 합니다.
-
외부 컴포넌트 통합: React나 Vue와 같은 외부 컴포넌트를 ERB 뷰에서 직접 사용할 수 있도록 지원하며, 엔진이 컴포넌트의 하이드레이션 및 마운팅을 처리합니다. Import maps를 사용하여 컴포넌트 종속성을 관리합니다.