importmap-rails를 사용한 JavaScript 모듈 로딩과 브라우저 환경 영향

Importmapを使ったJavaScriptの読み込みとブラウザアドオンの影響 / shu_numata - Kaigi on Rails 2024

3줄 요약

  • Rails 7에서 Webpacker를 대체하는 importmap-rails 도입 및 장점을 소개합니다.
  • importmap-rails 사용 중 애드 블록커가 JavaScript 모듈 로딩을 차단하는 문제에 직면했습니다.
  • 모듈을 로컬에 다운로드하여 제공하는 방식으로 문제를 해결했으나, 브라우저 환경의 영향에 대한 주의가 필요합니다.

본 발표는 Ruby on Rails 7 프로젝트에서 Webpacker를 대체하여 도입한 `importmap-rails` 사용 경험과 이로 인해 발생한 특정 문제 및 해결 방안에 대해 다룹니다. Rails 7로의 업데이트 과정에서 Webpacker의 은퇴와 함께 새로운 JavaScript 모듈 관리 방식을 모색하게 되었고, 빌드 도구 없이 브라우저 네이티브 모듈 로딩을 활용하는 `importmap-rails`를 선택하게 된 배경과 그 이점을 설명합니다.

Rails 7에서 importmap-rails가 기본으로 채택된 주요 이유는 최신 브라우저의 ES6 지원으로 Babel과 같은 트랜스파일러가 불필요해졌고, HTTP/2의 병렬 다운로드 기능으로 인해 여러 JavaScript 파일을 하나로 번들링할 필요성이 줄었기 때문입니다. importmap-rails를 사용하면 import 'module_name' from 'url'과 같이 CDN 등의 외부 URL에서 직접 모듈을 로드할 수 있게 되어 빌드 과정이 생략됩니다. 프로젝트에 importmap-rails를 도입하여 구성 단순화와 프론트엔드 성능 개선이라는 긍정적인 결과를 얻었습니다.

그러나 도입 후 서버 측에서 예상치 못한 오류가 발생했습니다. Turbo Stream 요청이 HTML 요청으로 바뀌는 현상이었습니다. 이는 Turbo가 정상적으로 작동하지 않을 때 나타날 수 있는 증상으로, Honeybadger와 같은 에러 트래킹 서비스에도 오류가 보고되지 않았습니다. 사용자 환경(최신 브라우저 사용 등)에 문제가 없어 보였기에, 사용자 브라우저의 확장 기능(Add-on)을 의심하게 되었습니다. 번역 기능이나 광고 차단 기능(AdBlock) 등을 테스트한 결과, AdBlock이 활성화될 때 문제가 재현되었습니다.

심층 분석 결과, AdBlock이 사용하는 필터 목록(예: EasyPrivacy list)에 Honeybadger와 관련된 URL 문자열이 포함되어 있어 importmap-rails를 통해 CDN에서 로드하려던 Honeybadger JavaScript 모듈이 차단되었음을 확인했습니다. 애플리케이션의 JavaScript 코드는 에러 트래킹 설정 등 초기에 로드되는 모듈에 의존성이 있었기 때문에, Honeybadger 모듈 로딩 실패가 전체 JavaScript 코드의 작동 중단으로 이어졌습니다. 결과적으로 Turbo 기능이 비활성화되어 Turbo Stream 요청 대신 일반 HTML 요청이 발생했던 것입니다.

이 문제는 importmap-rails가 브라우저에서 직접 외부 URL의 모듈을 로드하는 방식 때문에 발생한 것으로, 기존 Webpacker처럼 모듈을 번들링하여 애플리케이션 내에서 제공하는 방식에서는 발생하지 않았을 문제입니다. 브라우저 환경, 특히 사용자의 확장 기능에 더 민감해졌다는 것을 시사합니다.

해결 방안으로 importmap-rails의 다운로드 옵션(또는 버전 2+의 기본 동작)을 사용하여 문제가 된 JavaScript 모듈을 프로젝트의 vendor 디렉토리에 다운로드했습니다. 이렇게 로컬에 다운로드된 모듈은 Rails의 Asset Pipeline을 통해 제공되며, 고유한 핑거프린트가 파일명에 포함됩니다. 이로써 AdBlock의 필터 목록에 있는 문자열과 일치하지 않게 되어 모듈 차단 문제를 해결할 수 있었습니다. 실제로 이 변경 사항을 배포한 후 서버 측 오류가 사라졌습니다.

하지만 일부 복잡한 JavaScript 라이브러리의 경우, 하나의 엔트리 포인트 외에 추가적인 의존성 파일을 가지는 경우가 있어 importmap-rails의 다운로드 기능만으로는 모든 필요한 파일을 가져오지 못하는 한계가 있습니다. 따라서 현재는 다운로드가 용이한 모듈 외에는 여전히 외부 CDN을 사용하고 있으며, 이 경우 AdBlock 필터 목록 업데이트에 따라 향후 다시 문제가 발생할 가능성이 있음을 인지하고 있습니다. 이를 대비하여 주요 기능에서 요청 형식을 체크하는 로직을 추가하는 등 모니터링을 강화하고 있습니다.

`importmap-rails`는 JavaScript 빌드 과정을 제거하고 개발 및 배포를 단순화하는 강력한 도구이며, 프론트엔드 성능 개선에도 기여했습니다. 그러나 브라우저 네이티브 모듈 로딩 방식은 사용자 브라우저 환경, 특히 애드 블록커와 같은 확장 기능의 영향을 직접적으로 받을 수 있다는 점을 명심해야 합니다. 외부 의존성 로딩 시 발생 가능한 차단 문제를 인지하고, 모듈을 로컬에 다운로드하여 제공하거나 잠재적 문제를 감지할 수 있는 모니터링 체계를 갖추는 것이 중요합니다. `importmap-rails`의 이점을 활용하되, 브라우저 환경 변화에 대한 지속적인 관심과 대비가 필요합니다.