VS Code에서 Node.js 디버깅하기
Visual Studio Code 에디터는 Node.js 런타임을 위한 디버깅 지원이 내장되어 있으며, JavaScript, TypeScript 및 JavaScript로 트랜스파일되는 다른 많은 언어를 디버깅할 수 있습니다. VS Code는 적절한 Launch 설정 기본값과 스니펫을 제공하므로 Node.js 디버깅을 위한 프로젝트 설정이 간단합니다.
VS Code에서 Node.js 프로그램을 디버깅하는 방법에는 몇 가지가 있습니다:
- Auto Attach을 사용하여 VS Code의 통합 터미널에서 실행하는 프로세스를 디버깅합니다.
- JavaScript 디버그 터미널을 사용합니다( 통합 터미널과 유사).
- Launch 설정을 사용하여 프로그램을 시작하거나, VS Code 외부에서 시작된 프로세스에 연결합니다.
Auto Attach
Auto Attach 기능이 활성화되어 있으면 Node 디버거는 VS Code의 통합 터미널에서 시작된 특정 Node.js 프로세스에 자동으로 연결됩니다. 이 기능을 활성화하려면 명령 팔레트(Ctrl+Shift+P
)에서 Auto Attach Toggle 명령을 사용하거나, 이미 활성화된 경우 Auto Attach 상태 표시줄 항목을 사용하세요.
Auto Attach에는 세 가지 모드가 있으며, 퀵 픽이나 debug.javascript.autoAttachFilter 설정을 통해 선택할 수 있습니다:
smart
-node_modules
폴더 외부에서 스크립트를 실행하거나 mocha나 ts-node와 같은 일반적인 '실행기' 스크립트를 사용하는 경우 프로세스가 디버깅됩니다. Auto Attach Smart Pattern 설정(debug.javascript.autoAttachSmartPattern
)을 사용하여 '실행기' 스크립트 허용 목록을 구성할 수 있습니다.always
- 통합 터미널에서 시작된 모든 Node.js 프로세스가 디버깅됩니다.onlyWithFlag
---inspect
또는--inspect-brk
플래그와 함께 시작된 프로세스만 디버깅됩니다.
Auto Attach을 활성화한 후에는 터미널의 오른쪽 상단에 있는 ⚠ 아이콘을 클릭하거나 새 터미널을 만들어 터미널을 다시 시작해야 합니다. 그러면 디버거가 1초 이내에 프로 그램에 연결됩니다:
Auto Attach이 켜져 있으면 VS Code 창의 하단에 있는 상태 표시줄에 Auto Attach
항목이 나타납니다. 이를 클릭하면 Auto Attach 모드를 변경하거나 일시적으로 끌 수 있습니다. 일시적으로 Auto Attach을 끄는 것은 디버깅이 필요 없는 일회성 프로그램을 실행할 때 유용하지만, 이 기능을 완전히 비활성화하고 싶지는 않은 경우에 도움이 됩니다.
추가 구성
다른 Launch 설정 속성
일반적으로 launch.json에서 찾을 수 있는 다른 속성을 debug.javascript.terminalOptions 설정에서 Auto Attach에 적용할 수 있습니다. 예를 들어, node internals를 skipFiles에 추가하려면 사용자 또는 작업 영역 설정에 다음을 추가할 수 있습니다:
"debug.javascript.terminalOptions": {
"skipFiles": [
"<node_internals>/**"
]
},
Auto Attach 스마트 패턴
smart
Auto Attach 모드에서 VS Code는 디버깅하고 싶지 않은 빌드 도구가 아닌 코드에만 연결하려고 시도합니다. 이는 메인 스크립트를 glob 패턴 목록과 대조하여 수행됩니다. glob 패턴은 debug.javascript.autoAttachSmartPattern 설정에서 구성할 수 있으며 기본값은 다음과 같습니다:
[
"!**/node_modules/**", // node_modules 폴더의 스크립트 제외
"**/$KNOWN_TOOLS$/**", // 일반적인 도구는 포함
];
$KNOWN_TOOLS$
는 ts-node
, mocha
, ava
등과 같은 일반적인 '코드 실행기' 목록으로 대체됩니다. 이러한 설정이 작동하지 않는 경우 이 목록을 수정할 수 있습니다. 예를 들어 mocha
를 제외하고 my-cool-test-runner
를 포함하려면 두 줄을 추가할 수 있습니다:
[
"!**/node_modules/**",
"**/$KNOWN_TOOLS$/**",
"!**/node_modules/mocha/**", // "!"를 사용하여 "mocha" node modules의 모든 스크립트 제외
"**/node_modules/my-cool-test-runner/**", // 사용자 지정 테스트 실행기의 스크립트 포함
];
JavaScript 디버그 터미널
Auto Attach과 비슷한 방식으로 JavaScript 디버그 터미널은 그 안에서 실행하는 모든 Node.js 프로세스를 자동으로 디버깅합니다. 명령 팔레트(Ctrl+Shift+P
)에서 Debug: Create JavaScript Debug Terminal 명령을 실행하거나 터미널 전환기 드롭다운에서 Create JavaScript Debug Terminal을 선택하여 디버그 터미널을 생성할 수 있습니다.
추가 구성
다른 Launch 설정 속성
일반적으로 launch.json에서 찾을 수 있는 다른 속성을 debug.javascript.terminalOptions 설정에서 디버그 터미널에 적용할 수 있습니다. 예를 들어, node internals를 skipFiles에 추가하려면 사용자 또는 작업 영역 설정에 다음을 추가할 수 있습니다:
"debug.javascript.terminalOptions": {
"skipFiles": [
"<node_internals>/**"
]
},
Launch 설정
Launch 설정은 VS Code에서 디버깅을 설정하는 전통적인 방법이며, 복잡한 애플리케이션을 실행하기 위한 가장 많은 구성 옵션을 제공합니다.
이 섹션에서는 더 고급 디버깅 시나리오를 위한 구성과 기능에 대해 자세히 설명합니다. 소스 맵을 사용한 디버깅, 외부 코드 건너뛰기, 원격 디버깅 등에 대한 지침을 찾을 수 있습니다.
입문 영상을 보고 싶다면 VS Code에서 디버깅 시작하기를 참조하세요.
VS Code를 처음 사용하는 경우 일반 디버깅 기능과 launch.json
구성 파일 생성에 대해서는 디버깅 주제에서 배울 수 있습니다.
Launch 설정 속성
디버깅 구성은 작업 영역의 .vscode
폴더에 있는 launch.json
파일에 저장됩니다. 디버깅 구성 파일의 생성과 사용에 대한 소개는 일반 디버깅 문서에 있습니다.
아래는 Node.js 디버거에 특화된 일반적인 launch.json
속성 참조입니다. 전체 옵션 세트는 vscode-js-debug 옵션 문서에서 볼 수 있습니다.
다음 속성들은 launch
와 attach
타입의 Launch 설정에서 지원됩니다:
outFiles
- 생성된 JavaScript 파일을 찾기 위한 glob 패턴 배열입니다. 소스 맵 섹션을 참조하세요.resolveSourceMapLocations
- 소스 맵을 파싱해야 하는 위치에 대한 glob 패턴 배열입니다. 소스 맵 섹션을 참조하세요.timeout
- 세션을 다시 시작할 때 이 밀리초 후에 포기합니다. Node.js에 연결하기 섹션을 참조하세요.stopOnEntry
- 프로그램이 시작될 때 즉시 중단합니다.localRoot
- VS Code의 루트 디렉토리입니다. 아래 원격 디버깅 섹션을 참조하세요.remoteRoot
- Node의 루트 디렉토리입니다. 아래 원격 디버깅 섹션을 참조하세요.smartStep
- 소스 파일에 매핑되지 않는 코드를 자동으로 건너뛰려고 시도합니다. 스마트 스테핑 섹션을 참조하세요.skipFiles
- 이러한 glob 패턴이 적용되는 파일을 자동으로 건너뜁니다. 관심 없는 코드 건너뛰기 섹션을 참조하세요.trace
- 진단 출력을 활성화합니다.
다음 속성들은 launch
요청 타입의 Launch 설정에서만 사용할 수 있습니다:
program
- 디버깅할 Node.js 프로그램의 절대 경로입니다.args
- 디버깅할 프로그램에 전 달되는 인수입니다. 이 속성은 배열 타입이며 개별 인수를 배열 요소로 받습니다.cwd
- 이 디렉토리에서 디버깅할 프로그램을 시작합니다.runtimeExecutable
- 사용할 런타임 실행 파일의 절대 경로입니다. 기본값은node
입니다. 'npm'과 다른 도구를 위한 Launch 설정 지원 섹션을 참조하세요.runtimeArgs
- 런타임 실행 파일에 전달되는 선택적 인수입니다.runtimeVersion
- "nvm"(또는 "nvm-windows")이나 "nvs"를 사용하여 Node.js 버전을 관리하는 경우, 이 속성을 사용하여 특정 Node.js 버전을 선택할 수 있습니다. 아래 다중 버전 지원 섹션을 참조하세요.env
- 선택적 환경 변수입니다. 이 속성은 문자열 타입의 키/값 쌍 목록으로 환경 변수를 받습니다.envFile
- 환경 변수 정의가 포함된 파일의 선택적 경로입니다. 아래 외부 파일에서 환경 변수 로드 섹션을 참조하세요.console
- 프로그램을 시작할 콘솔(internalConsole
,integratedTerminal
,externalTerminal
)입니다. 아래 Node 콘솔 섹션을 참조하세요.outputCapture
-std
로 설정하면 디버그 포트를 통해 출력을 수신하는 대신 프로세스 stdout/stderr의 출력이 디버그 콘솔에 표시됩니다. 이는console.*
API 대신 stdout/stderr 스트림에 직접 쓰는 프로그램이나 로그 라이브러리에 유용합니다.
다음 속성은 attach
요청 타입의 Launch 설정에서만 사용할 수 있습니다:
restart
- 종료 시 연결을 다시 시작합니다. 소스가 편집될 때 자동으로 디버그 세션 다시 시작하기 섹션을 참조하세요.port
- 사용할 디버그 포트입니다. Node.js에 연결하기와 원격 디버깅 섹션을 참조하세요.address
- 디버그 포트의 TCP/IP 주소입니다. Node.js에 연결하기와 원격 디버깅 섹션을 참조하세요.processId
- USR1 신호를 보낸 후 디버거가 이 프로세스에 연결을 시도합니다. 이 설정을 사용하면 디버거는 디버그 모드로 시작되지 않은 이미 실행 중인 프로세스에 연결할 수 있습니다.processId
속성을 사용할 때는 Node.js 버전(및 사용된 프로토콜)을 기반으로 디버그 포트가 자동으로 결정되므로 명시적으로 구성할 수 없습니다. 따라서port
속성을 지정하지 마세요.continueOnAttach
- 연결할 때 일시 중지된 프로세스를 계속 실행할지 여부입니다. 이 옵션은--inspect-brk
로 프로그램을 시작할 때 유용합니다.
일반적인 시나리오를 위한 Launch 설정
launch.json
파일에서 IntelliSense(Ctrl+Space
)를 트리거하여 일반적으로 사용되는 Node.js 디버깅 시나리오에 대한 Launch 설정 스니펫을 볼 수 있습니다.
launch.json
편집기 창의 오른쪽 하단에 있는 구성 추가... 버튼으로도 스니펫을 불러올 수 있습니다.
다음 스니펫들을 사용할 수 있습니다:
- 프로그램 시작: 디버그 모드에서 Node.js 프로그램을 시작합니다.
- npm으로 시작: npm 'debug' 스크립트를 통해 Node.js 프로그램을 시작합니다. package.json에 정의된 경우 Launch 설정에서 npm debug 스크립트를 사용할 수 있습니다. npm 스크립트에서 사용되는 디버그 포트는 스니펫에 지정된 포트와 일치해야 합니다.
- 연결: 로컬에서 실행 중인 Node.js 프로그램의 디버그 포트에 연결합니다. 디버깅할 Node.js 프로그램이 디버그 모드로 시작되었는지, 그리고 사용된 디버그 포트가 스니펫에 지정된 포트와 같은지 확인하세요.
- 원격 프로그램에 연결:
address
속성에 지정된 호스트에서 실행 중인 Node.js 프로그램의 디버그 포트에 연결합니다. 디버깅할 Node.js 프로그램이 디버그 모드로 시작되었는지, 그리고 사용된 디버그 포트가 스니펫에 지정된 포트와 같은지 확인하세요. VS Code가 작업 영역과 원격 호스트의 파일 시스템 간에 소스 파일을 매핑하는 데 도움이 되도록localRoot
와remoteRoot
속성에 올바른 경로를 지정했는지 확인하세요. - 프로세스 ID로 연결: node 또는 gulp 프로세스를 선택하여 디버깅하기 위한 프로세스 선택기를 엽니다. 이 Launch 설정을 사용하면 디버그 모드로 시작되지 않은 node 또는 gulp 프로세스에도 연결할 수 있습니다.
- Nodemon 설정: JavaScript 소스가 변경될 때마다 디버그 세션을 자동으로 다시 시작하기 위해 nodemon을 사용합니다. nodemon이 전역적으로 설치되어 있는지 확인하세요. 디버그 세션을 종료하면 디버깅할 프로그램만 종료되고 nodemon 자체는 종료되지 않습니다. nodemon을 종료하려면 통합 터미널에서
Ctrl+C
를 누르세요. - Mocha 테스트: 프로젝트의
test
폴더에 있는 mocha 테스트를 디버깅합니다. 프로젝트의node_modules
폴더에 'mocha'가 설치되어 있는지 확인하세요. - Yeoman 생성기: yeoman 생성기를 디버깅합니다. 스니펫은 생성기의 이름을 지정하도록 요청합니다. 프로젝트의
node_modules
폴더에 'yo'가 설치되어 있고, 생성된 프로젝트가 프로젝트 폴더에서npm link
를 실행하여 디버깅을 위해 설치되었는지 확인하세요. - Gulp 작업: gulp 작업을 디버깅합니다. 프로젝트의
node_modules
폴더에 'gulp'가 설치되어 있는지 확인하세요. - Electron 메인: Electron 애플리케이션의 메인 Node.js 프로세스를 디버깅합니다. 스니펫은 Electron 실행 파일이 작업 영역의
node_modules/.bin
디렉터리 안에 설치되어 있다고 가정합니다.
Node 콘솔
기본적으로 Node.js 디버그 세션은 내부 VS Code 디버그 콘솔에서 대상을 시작합니다. 디버그 콘솔은 콘솔에서 입력을 읽어야 하는 프로그램을 지원하지 않으므로, Launch 설정에서 console
속성을 externalTerminal
또는 integratedTerminal
로 설정하여 외부 터미널이나 VS Code 통합 터미널을 활성화할 수 있습니다. 기본값은 internalConsole
입니다.
외부 터미널에서는 terminal.external.windowsExec
, terminal.external.osxExec
, terminal.external.linuxExec
설정을 통해 사용할 터미널 프로그램을 구성할 수 있습니다.
'npm'과 다른 도구를 위한 Launch 설정 지원
node로 Node.js 프로그램을 직접 시작하는 대신, Launch 설정에서 'npm' 스크립트나 다른 태스크 실행기 도구를 직접 사용할 수 있습니다:
runtimeExecutable
속성에 PATH에서 사용 가능한 모든 프로그램(예: 'npm', 'mocha', 'gulp' 등)을 사용할 수 있으며runtimeArgs
를 통해 인수를 전달할 수 있습니다.- npm 스크립트나 다른 도구가 암시적으로 시작할 프로그램을 지정하는 경우
program
속성을 설정할 필요가 없습니다.
'npm' 예제를 살펴보겠습니다. package.json
에 'debug' 스크립트가 있는 경우, 예를 들어:
"scripts": {
"debug": "node myProgram.js"
},
해당하는 Launch 설정은 다음과 같습니다:
{
"name": "npm으로 시작",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "npm",
"runtimeArgs": ["run-script", "debug"]
}
다중 버전 지원
'nvm'(또는 'nvm-windows')이나 'nvs'를 사용하여 Node.js 버전을 관리하는 경우, Launch 설정에서 runtimeVersion
속성을 사용하여 특정 Node.js 버전을 선택할 수 있습니다:
{
"type": "node",
"request": "launch",
"name": "테스트 시작",
"runtimeVersion": "14",
"program": "${workspaceFolder}/test.js"
}
'nvs'를 사용하여 Node.js 버전을 관리하는 경우, runtimeVersion
속성을 사용하여 특정 버전, 아키텍처, 그리고 Node.js 종류를 선택할 수 있습니다. 예를 들어:
{
"type": "node",
"request": "launch",
"name": "테스트 시작",
"runtimeVersion": "chackracore/8.9.4/x64",
"program": "${workspaceFolder}/test.js"
}
이 기능은 버전을 자동으로 다운로드하고 설치하지 않으므로, runtimeVersion
속성에서 사용하려는 Node.js 버전이 설치되어 있는지 확인하세요. 예를 들어, Launch 설정에 "runtimeVersion": "7.10.1"
을 추가할 계획이라면 통합 터미널에서 nvm install 7.10.1
또는 nvs add 7.10.1
과 같은 명령을 실행해야 합니다.
마이너 버전과 패치 버전을 생략하고 예를 들어 "runtimeVersion": "14"
를 사용하면, 시스템에 설치된 가장 최신 14.x.y
버전이 사용됩니다.
외부 파일에서 환경 변수 로드
VS Code Node 디버거는 파일에서 환경 변수를 로드하여 Node.js 런타임에 전달하는 기능을 지원합니다. 이 기능을 사용하려면 Launch 설정에 envFile
속성을 추가하고 환경 변수가 포함된 파일의 절대 경로를 지정하세요:
//...
"envFile": "${workspaceFolder}/.env",
"env": { "USER": "john doe" }
//...
env
딕셔너리에 지정된 모든 환경 변수는 파일에서 로드된 변수를 재정의합니다.
다음은 .env
파일의 예시입니다:
USER=doe
PASSWORD=abc123
# 주석
# 빈 값:
empty=
# 따옴표로 묶인 문자열에서 새 줄이 확장됨:
lines="foo\nbar"
Node.js에 연결하기
외부 Node.js 프로그램에 VS Code 디버거를 연결하려면 다음과 같이 Node.js를 시작하세요:
node --inspect program.js
또는 프로그램이 바로 실행되지 않고 디버거가 연결될 때까지 기다려야 하는 경우:
node --inspect-brk program.js
프로그램에 디버거를 연결하는 방법:
- 모든 잠재적 후보 프로세스를 나열하고 하나를 선택할 수 있는 "process picker"를 열거나,
- 모든 구성 옵션을 명시적으로 지정하는 "attach" 구성을 만든 다음 F5를 누릅니다.
이러한 옵션들을 자세히 살펴보겠습니다:
Node 프로세스에 연결 작업
명령 팔레트(Ctrl+Shift+P
)의 Node 프로세스에 연결 명령은 Node.js 디버거에서 사용할 수 있는 모든 잠재적 프로세스를 나열하는 퀵 픽 메뉴를 엽니다:
선택기에 나열된 개별 프로세스는 디버그 포트와 프로세스 ID를 보여줍니다. 그 목록에서 Node.js 프로세스를 선택하면 Node.js 디버거가 해당 프로세스에 연결을 시도합니다.
Node.js 프로세스 외에도 선택기는 다양한 형태의 --inspect
인수로 시작된 다른 프로그램도 보여줍니다. 이를 통해 Electron이나 VS Code의 헬퍼 프로세스에도 연결할 수 있습니다.
"Attach" 구성 설정하기
이 옵션은 더 많은 작업이 필요하지만 이전 두 옵션과 달리 다양한 디버그 구성 옵션을 명시적으로 구성할 수 있습니다.
가장 간단한 "Attach" 구성은 다음과 같습니다:
{
"name": "프로세스에 연결",
"type": "node",
"request": "attach",
"port": 9229
}
포트 9229
는 --inspect
와 --inspect-brk
옵션의 기본 디버그 포트입니다. 다른 포트(예: 12345
)를 사용하려면, 옵션에 다음과 같이 추가하고: --inspect=12345
와 --inspect-brk=12345
, Launch 설정의 port
속성도 이에 맞춰 변경하세요.
디버그 모드로 시작되지 않은 Node.js 프로세스에 연결하려면 Node.js 프로세스의 프로세스 ID를 문자열로 지정하면 됩니다:
{
"name": "프로세스에 연결",
"type": "node",
"request": "attach",
"processId": "53426"
}
Launch 설정에 새 프로세스 ID를 반복해서 입력하는 것을 피하기 위해, Node 디버그는 프로세스 선택기(위에서 설명)를 열 수 있는 PickProcess
명령 변수를 지원합니다.
PickProcess
변수를 사용한 Launch 설정은 다음과 같습니다:
{
"name": "프로세스에 연결",
"type": "node",
"request": "attach",
"processId": "${command:PickProcess}"
}
디버깅 중지
Debug: Stop 작업(디버그 도구 모음에서 사용 가능하거나 Command Palette를 통해)을 사용하여 디버그 세션을 중지합니다.
디버그 세션이 "연결" 모드로 시작된 경우(그리고 디버그 도구 모음의 빨간색 종료 버튼에 "플러그" 아이콘이 겹쳐져 있는 경우), Stop를 누르면 Node.js 디버거가 디버기(계속 실행되는)에서 연결 해제됩니다.
디버그 세션이 "시작" 모드인 경우, Stop를 누르면 다음과 같이 동작합니다:
-
Stop를 처음 누르면
SIGINT
신호를 보내 디버기에 정상적인 종료를 요청합니다. 디버기는 이 신호를 가로채서 필요에 따라 정리 작업을 수행한 후 종료할 수 있습니다. 종료 코드에 중단점이 없는 경우(또는 문제가 없는 경우) 디버기와 디버그 세션이 종료됩니다. -
그러나 디버거가 종료 코드의 중단점에 도달하거나 디버기가 자체적으로 적절하게 종료되지 않는 경우, 디버그 세션은 종료되지 않습니다. 이 경우, Stop를 다시 누르면 디버기와 그 자식 프로세스를 강제 종료합니다(
SIGKILL
).
빨간색 Stop 버튼을 눌렀을 때 디버그 세션이 종료되지 않는 것을 보면, 버튼을 다시 눌러 디버기를 강제 종료하세요.
Windows에서는 Stop를 누르면 디버기와 그 자식 프로세스를 강제 종료합니다.
소스 맵
VS Code의 JavaScript 디버거는 TypeScript나 축소/난독화된 JavaScript와 같은 트랜스파일된 언어의 디버깅을 돕는 소스 맵을 지원합니다. 소스 맵을 사용하면 원본 소스에서 단계별 실행을 하거나 중단점을 설정할 수 있습니다. 원본 소스에 대한 소스 맵이 없거나, 소스 맵이 손상되어 소스와 생성된 JavaScript 간의 매핑이 불가능한 경우 중단점은 확인되지 않은 상태(회색 빈 원)로 표시됩니다.
sourceMaps
속성은 기본값이 true
이며 소스 맵 기능을 제어합니다. 디버거는 항상 소스 맵을 사용하려고 시도하며(찾을 수 있는 경우), 결과적으로 program
속성에 소스 파일(예: app.ts)을 지정할 수도 있습니다. 어떤 이유로 소스 맵을 비활성화해야 하는 경우, sourceMaps
속성을 false
로 설정할 수 있습니다.
도구 구성
소스 맵이 항상 자동으로 생성되는 것은 아니므로, 트랜스파일러가 소스 맵을 생성하도록 구성해야 합니다. 예를 들어:
TypeScript
TypeScript의 경우, tsc
에 --sourceMap
을 전달하거나 tsconfig.json 파일에 "sourceMap": true
를 추가하여 소스맵을 활성화할 수 있습니다.
tsc --sourceMap --outDir bin app.ts
Babel
Babel의 경우, sourceMaps 옵션을 true
로 설정하거나, 코드를 컴파일할 때 --source-maps
옵션을 전달해야 합니다.
npx babel script.js --out-file script-compiled.js --source-maps
Webpack
Webpack은 많은 소스 맵 옵션을 가지고 있습니다. 최상의 결과를 위해 webpack.config.js
에서 devtool: "source-map"
속성을 설정하는 것을 권장하지만, 다른 설정이 빌드 속도를 저하시키는 경우 다른 설정을 시도해볼 수 있습니다.
또한, TypeScript 로더와 같은 추가 컴파일 단계가 webpack에 있는 경우, 이러한 단계도 소스맵을 생성하도록 설정되어 있는지 확인해야 합니다. 그렇지 않으면 webpack이 생성하는 소스맵이 실제 소스 대신 로더에서 컴파일된 코드로 매핑됩니다.
소스 맵 검색
기본적으로 VS Code는 node_modules
를 제외한 전체 작업 영역에서 소스맵을 검색합니다. 큰 작업 영역에서는 이 검색이 느릴 수 있습니다. launch.json
의 outFiles
속성을 설정하여 VS Code가 소스 맵을 검색할 위치를 구성할 수 있습니다. 예를 들어, 이 구성은 bin
폴더의 .js
파일에 대한 소스맵만 검색합니다:
{
"version": "0.2.0",
"configurations": [
{
"name": "TypeScript 시작",
"type": "node",
"request": "launch",
"program": "app.ts",
"outFiles": ["${workspaceFolder}/bin/**/*.js"]
}
]
}
outFiles
는 소스 맵 파일(.map
으로 끝날 수 있음)이 아닌 JavaScript 파일과 일치해야 합니다.
소스 맵 처리
기본적으로 outFiles
의 소스 맵만 처리됩니다. 이 동작은 종속성이 설정한 중단점을 방해하는 것을 방지하기 위해 사용됩니다. 예를 들어, src/index.ts
파일이 있고 종속성이 webpack:///./src/index.ts
를 참조하는 소스 맵을 가지고 있다면, 이는 잘못되게 소스 파일로 처리되어 예상치 못한 결과를 초래할 수 있습니다.
resolveSourceMapLocations
옵션을 설정하여 이 동작을 구성할 수 있습니다. null
로 설정하면 모든 소스 맵이 처리됩니다. 예를 들어, 이 구성은 추가로 node_modules/some-dependency
의 소스 맵도 처리되도록 허용합니다:
"resolveSourceMapLocations": [
"out/**/*.js",
"node_modules/some-dependency/**/*.js",
]
스마트 스테핑
Launch 설정에서 smartStep
속성을 true
로 설정하면, VS Code는 디버거에서 코드를 단계별로 실행할 때 '관심 없는 코드'를 자동으로 건너뜁니다. '관심 없는 코드'는 트랜스파일 프로세스에 의해 생성되었지만 소스 맵으로 커버되지 않아 원본 소스로 다시 매핑되지 않는 코드입니다. 이 코드는 디버거에서 소스 코드를 단계별로 실행할 때 원본 소스 코드와 생성된 코드(관심 없는) 사이를 전환해야 하므로 방해가 됩니다. smartStep
은 소스 맵으로 커버되지 않는 코드를 자동으로 건너뛰어 소스 맵으로 커버되는 위치에 도달할 때까지 진행합니다.
스마트 스테핑은 TypeScript의 async/await 다운컴파일과 같이 컴파일러가 소스 맵으로 커버되지 않는 헬퍼 코드를 주입하는 경우에 특히 유용합니다.
smartStep
기능은 소스에서 생성되어 따라서 소스 맵을 가지고 있는 JavaScript 코드에만 적용됩니다. 소스가 없는 JavaScript의 경우, 스마트 스테핑 옵션은 효과가 없습니다.
JavaScript 소스 맵 팁
소스 맵으로 디버깅할 때 흔한 문제는 중단점을 설정했는데 회색으로 변하는 것입니다. 커서를 그 위에 올려놓으면 "Breakpoint ignored because generated code not found (source map problem?)"
메시지가 표시됩니다. 이제 어떻게 해야 할까요? 이런 상황을 초래할 수 있는 다양한 문제가 있습니다. 먼저 Node 디버그 어댑터가 소스 맵을 처리하는 방식을 간단히 설명하겠습니다.
app.ts
에 중단점을 설정하면, 디버그 어댑터는 실제로 Node에서 실행되는 TypeScript 파일의 트랜스파일된 버전인 app.js
의 경로를 찾아야 합니다. 하지만 .ts
파일에서 시작하여 이를 알아내는 간단한 방법은 없습니다. 대신, 디버그 어댑터는 launch.json
의 outFiles
속성을 사용하여 모든 트랜스파일된 .js
파일을 찾고, 연관된 .ts
파일의 위치가 포함된 소스 맵을 파싱합니다.
TypeScript에서 소스 맵을 활성화하고 app.ts
파일을 빌드하면, app.js.map
파일이 생성되거나 app.js
파일 하단에 base64로 인코딩된 문자열로 인라인 소스 맵이 생성됩니다. 이 맵과 연관된 .ts
파일을 찾기 위해 디버그 어댑터는 소스 맵에서 두 가지 속성인 sources
와 sourceRoot
를 확인합니다. sourceRoot
는 선택사항입니다 - 존재하는 경우 경로 배열인 sources
의 각 경로 앞에 추가됩니다. 결과는 .ts
파일에 대한 절대 또는 상대 경로의 배열입니다. 상대 경로는 소스 맵을 기준으로 해석됩니다.
마지막으로 디버그 어댑터는 이 .ts
파일 목록에서 app.ts
의 전체 경로를 검색합니다. 일치하는 것이 있으면 app.ts
를 app.js