[ASP.NET] JavaScript Source Map

2016. 12. 26. 09:23WEB

JavaScript를 서버에 배포할 때는 여러 소스파일을 하나로 압축하고 난독화 하게 됩니다. 이렇게 코드를 하나로 통합하는 것을 Bundling, 코드를 압축하고 난독화 하는 것을 Minification이라고 합니다. 이를 통해 코드 크기를 줄일 수 있고, 실행성능을 향상시키며, 다른사람에게 실행코드가 노출될 가능성을 줄일 수 있습니다.


압축된 Javascript 코드

하지만 이렇게 통합되고 난독화된 JavaScript 코드를 디버깅해야하는 상황이 발생하면 난감해집니다. 이때 JavaScript Source Map을 통해 실행성능에 영향을 주지않으면서 코드를 다시 읽기좋게 복원하고 디버깅까지 하실 수 있습니다.


이렇게 코드를 복원한 상태로 디버깅을 지원합니다.

Source Map 개발배경

Source Map은 Bunding & Minification이 진행된 JavaScript 코드를 원래 상태로 되돌려주는 기술을 말합니다. 이 기술은 2009년 구글이 진행한 『JavaScript를 통해 쉽고 빠른 웹어플리케이션 개발』을 지원하는 Google Closure 프로젝트로부터 유래하였습니다. Google Closure는 코드분석 도구인 Closure Inspector 도구를 함께 제공했는데 이 도구의 기능 중 하나가 Bunding & Minification이 진행된 JavaScript Source Code를 이전 상태로 되돌려 디버깅 하기 쉽도록 지원하는 것이 었습니다. Source Map은 당시 Closure Inspector 프로젝트에 참여했던 Joseph Schor에 의해 원안이 만들어지고, 점점 발전하여 현재 Revision 3에 이르렀으며 자세한 내용은 여기에서 확인하실 수 있습니다.

Source Map 생성

ASP.NET MVC Project에서 사용할 수 있는 System.Web.Optimization Bundling은 Source Map을 지원하지 않습니다. 대신 Bundler & Minifier 도구를 통해 Source Map 생성을 지원합니다. ASP.NET Core Project부터는 기본적으로 Bundler & Minifier를 통해 Bundling & Minification을 진행하게 됩니다.

Bundler & Minifier 설치

기존 ASP.NET MVC 혹은 WebForms Project를 사용하시는 경우 Bundler & Minifier 도구를 통해 Source Map을 지원합니다.

  1. Visual Studio 상단 메뉴에서 Tools / Extensions and Updates...를 선택합니다.
  2. Bundler & Minifier 도구를 설치합니다.

Source Map 생성

Bundler & Minifier 설치를 완료하셨으면 Bundling 파일을 다음과 같이 생성하실 수 있습니다.

  1. Bundling할 대상 Script를 선택하시고, 마우스 우클릭을 통해 Bundle and Minify Files를 실행합니다.
  2. Bundle 결과파일이 저장될 위치를 지정합니다.
  3. 통합되고 압축된 bundle.js 파일이 생성된 것을 보실수 있습니다. Bundle 파일이 한번 생성되면 소스코드를 수정하고 저장하실 때마다 Bundle 파일이 자동 재생성되므로 매번 생성하실 필요 없습니다.
  4. Bundling 설정은 프로젝트 루트에 생성된 bundleconfig.json 파일을 통해서 진행하실 수 있습니다. Bundling 대상파일 순서조정, 추가, 삭제 등을 진행하실 수 있습니다. 여기에서 'sourceMap' Key를 추가하신 후 저장하시면 source Map파일이 자동생성됩니다.

    [
        //JavaScript
        {
            "outputFileName": "Scripts/bundle.js",
            "inputFiles":
            [
                "Scripts/jquery-1.10.2.js",
                "Scripts/jquery.validate.js",
                        ...
            ],
    
            //Source Map을 사용하시려면 true로 설정
            "sourceMap": true
        },
        //CSS
        {
            "outputFileName": "Content/bundle.css",
            "inputFiles":
            [
                "wwwroot/css/site.css",
                        ...
            ]
        }
    ]
  5. .map이라는 확장자를 가진 Source Map 파일이 생성됩니다. 
    .

Source Map 파일

생성된 Source Map파일은 다음과 같습니다.

{
    "version":3,                //Revision 3을 뜻함
    "file":"bundle.min.js",     //SourceMapping 대상
    "sources":["bundle.js"],    //원본파일
    "sourceRoot":"",            //Sources 파일의 경로(생략가능)
    "sourcesContent":[null],    //Sources 대신 파일내용을 지정할 경우 사용
    "lineCount":56,             //파일길이(생략가능)
    "mappings":";;;EAoSd,CAAC,IAAD,CAAM ...",   //매핑된 문자열
    "names":["window","undefined","obj" ...]    //원본 문자열
}

Sources에 원본파일 경로를 입력하시는 대신 sourcesContent에 해당 파일의 내용을 기술해도 됩니다. sources와 souncesContent 둘중 하나는 제공되어야 합니다.

브라우저 지원

Source Map은 Chrome, Firefox(23+), IE, Edge, Safari 등 대부분의 브라우저에서 지원하고 있습니다. 아래 그림과 같이 생성된 파일을 모두 서버에 게시하시면 브라우저 개발도구는 자동으로 Source Mapping을 인식하고 지원하게 됩니다.

[서버에 아래파일을 모두 업로드하시면 됩니다]

간혹 일부 브라우저에서는 Source Map을 설정에서 직접 활성화 해야할 수 있습니다.



알려진 문제점

원본 변수명을 통해 변수값을 확인할 수 없습니다. Source Map을 통해 소스코드가 복원된 것처럼 보일 뿐 실제로는 그렇지 않기 때문입니다. 따라서 변수값이나 객체의 상태를 확인하시려면 항상 t, j와 같은 압축된 변수명을 통해 값을 조회하셔야 합니다.

Resources