IT관련

소스맵(.map 파일)의 핵심 구성 요소

파란하늘999 2025. 9. 16. 13:31
ng build 시 생성되는 .js.map 파일 안에는 다음과 같은 중요한 정보들이 JSON 형식으로 저장되어 있습니다.
  1. version: 사용된 소스맵의 버전 (현재는 대부분 3).
  2. file: 이 소스맵 파일이 가리키는 대상 파일 (예: main.js).
  3. sourceRoot: 소스 파일들의 기준 경로.
  4. sources: 원본 소스 파일들의 목록 (예: ["app.component.ts", "main.ts", "user.service.ts"]).
  5. sourcesContent: 원본 소스 파일들의 실제 내용 전체가 문자열로 포함되어 있습니다. (이 때문에 소스맵이 노출되면 소스 코드 전체가 노출됩니다.)
  6. names: 코드에 사용된 변수명, 함수명 등의 목록 (예: ["AppComponent", "title", "userService"]).
  7. mappings: 가장 핵심적인 부분으로, 압축된 코드의 위치와 원본 코드의 위치를 연결하는 암호화된 문자열입니다.

소스맵이 원본 소스를 보여주는 과정

브라우저 개발자 도구가 소스맵을 사용하여 원본 코드를 보여주는 과정은 다음과 같습니다.

1단계: 소스맵 파일 로드

  • 브라우저가 .js 파일을 로드합니다.
  • 개발자 도구가 열려 있으면, 브라우저는 해당 .js 파일에 대한 소스맵을 찾습니다.
    • hidden: false인 경우: .js 파일 맨 아래에 있는 //# sourceMappingURL=main.js.map 주석을 보고 main.js.map 파일을 서버에 요청하여 로드합니다.
    • hidden: true인 경우: 개발자가 수동으로 소스맵을 연결하면(예: URL 입력, 로컬 파일 지정), 브라우저가 해당 소스맵을 로드합니다.

2단계: mappings 정보 해독

  • 브라우저는 로드한 .map 파일에서 가장 중요한 mappings 문자열을 해독하기 시작합니다.
  • mappings는 **Base64 VLQ (Variable Length Quantity)**라는 형식으로 인코딩된 매우 긴 문자열입니다. (예: AAAA,SAASA,MAAM,CAACC,GAAG,EAAEC,IAAI,EAAE;...)
  • 이 문자열은 겉보기에는 의미 없어 보이지만, 실제로는 압축된 코드의 (줄, 열) 위치원본 파일의 인덱스, 원본 파일의 (줄, 열) 위치, 그리고 원본 변수/함수명의 인덱스를 연결하는 수많은 좌표 정보들을 담고 있습니다.
    예시 (개념적):
    • main.js의 1번째 줄, 10번째 열에 있는 코드는 -> app.component.ts 파일의 5번째 줄, 4번째 열에 있는 title 변수에 해당한다.
    • main.js의 1번째 줄, 25번째 열에 있는 코드는 -> user.service.ts 파일의 12번째 줄, 8번째 열에 있는 getUser 함수에 해당한다.

3단계: 가상 파일 시스템 생성 및 원본 코드 표시

  • 브라우저 개발자 도구는 해독한 mappings 정보와 .map 파일에 포함된 sources (원본 파일 목록) 및 sourcesContent (원본 파일 내용)를 사용하여 메모리 상에 가상의 파일 시스템을 만듭니다.
  • Sources 탭의 왼쪽 패널을 보면, 실제 서버에는 없는 webpack:// 또는 ng:// 같은 가상 경로와 함께 app.component.ts, user.service.ts 같은 원본 파일들이 트리 구조로 나타나는 것을 볼 수 있습니다. 이것이 바로 소스맵 정보를 기반으로 재구성된 가상 파일 시스템입니다.
  • 사용자가 이 가상 파일 시스템에서 app.component.ts를 클릭하면, 개발자 도구는 .map 파일의 sourcesContent에서 해당 파일의 내용을 가져와 보여줍니다.

4단계: 디버깅 (Breakpoint, 변수 확인 등)

  • 사용자가 원본 코드(예: app.component.ts의 10번째 줄)에 중단점(Breakpoint)을 설정하면, 개발자 도구는 mappings 정보를 역으로 참조하여 이 위치에 해당하는 압축된 main.js 코드의 실제 위치를 찾아냅니다.
  • 그리고 실제로 중단점을 거는 것은 압축된 main.js 코드의 해당 위치입니다.
  • 실행이 중단되면, 개발자 도구는 다시 mappings 정보를 사용하여 현재 실행 중인 압축된 코드의 변수들을 원본 코드의 변수명과 매핑하여 Scope나 Watch 창에 보여줍니다.

결론

결론적으로, 소스맵은 **압축된 코드와 원본 코드 사이의 모든 좌표를 기록한 거대한 지도(map)**입니다. 브라우저 개발자 도구는 이 지도를 해독하여, 사용자에게는 마치 원본 코드를 직접 실행하고 디버깅하는 것처럼 보이는 환상적인 경험을 제공해 주는 것입니다.
이 원리를 이해하면 왜 소스맵 파일이 노출되면 안 되는지, 그리고 hidden: true 옵션이 왜 중요한지 더욱 명확하게 알 수 있습니다.
반응형