개발/Visual Studio Code

VS Code 커맨드 팔레트 4부|Task 오류를 Problems 패널로 연결하는 Problem Matcher

반응형
VS CODE 초보자 시리즈 · 커맨드 팔레트 4부

Task 출력 오류를
Problems 패널로 연결하기

터미널에 흩어진 파일·줄·열·오류 메시지를 Problem Matcher가 읽을 수 있는 형식으로 만들고, 클릭 가능한 문제 항목으로 바꾸는 과정을 실습합니다.

이번 편의 핵심
3부에서 만든 Task는 반복 명령을 실행하는 데는 편리했지만, 실패 원인을 찾으려면 터미널 출력을 직접 읽어야 했습니다. 4부에서는 problemMatcher를 추가해 Task 출력의 문제를 편집기와 Problems 패널에서 바로 확인합니다.

1. Problem Matcher란 무엇인가

VS Code의 Problem Matcher는 Task가 터미널에 출력한 텍스트를 정규식으로 검사해, 파일 경로·줄·열·심각도·메시지를 추출하는 기능입니다.

출력 형식이 Problem Matcher의 패턴과 일치하면 VS Code는 해당 내용을 편집기 안의 문제 표시와 Problems 패널에 등록합니다. 초보자 입장에서는 긴 터미널 로그에서 파일 이름과 줄 번호를 직접 찾아갈 필요가 줄어듭니다.

흐름을 한 줄로 이해하기
Task 실행 → 도구가 오류 문장을 출력 → Problem Matcher가 정규식으로 분석 → Problems 패널과 편집기에 문제 표시

VS Code에는 TypeScript의 $tsc, TypeScript Watch의 $tsc-watch, ESLint의 $eslint-compact·$eslint-stylish처럼 미리 제공되는 Problem Matcher도 있습니다. 출력 형식이 다른 자체 검사 도구는 사용자 정의 Matcher를 만들 수 있습니다.

2. 왜 필요하고 언제 사용하는가

상황Problem Matcher가 하는 일기대 효과
Task 출력에 파일과 줄 번호가 있음파일·줄·열 정보를 문제 위치로 변환오류 위치를 빠르게 확인
자체 검사 스크립트를 사용함출력 규칙에 맞는 사용자 정의 패턴 적용별도 확장 없이 프로젝트 규칙 연결
터미널 로그가 길고 오류가 여러 개임Problems 패널에 문제만 모아서 표시경고와 오류를 한곳에서 검토
컴파일러·린터의 공식 Matcher가 있음$tsc 같은 내장 Matcher 재사용복잡한 정규식을 직접 작성하지 않음
오류 출력 형식이 일정하지 않음패턴이 일치하는 문장만 문제로 등록출력 형식을 먼저 정리해야 함
모든 터미널 문장을 자동으로 이해하는 기능은 아닙니다
Problem Matcher는 지정한 패턴과 일치하는 출력만 분석합니다. 파일 이름, 줄 번호, 메시지가 일정한 형식으로 출력되어야 합니다.

3. 예제 프로젝트 준비하기

3부의 command-palette-lab을 계속 사용해도 되지만, 이번 글만 따로 따라 하려면 다음 구조로 폴더를 만듭니다.

problem-matcher-lab/
├─ src/
│  └─ app.js
├─ scripts/
│  └─ check-code.js
├─ .vscode/
│  └─ tasks.json
└─ README.md

src/app.js

const userName = "VS Code";
const greeting = `Hello, ${userName}`;

console.log(greeting);
// TODO: 임시 코드를 정리하세요.
debugger;

README.md

# Problem Matcher Lab

Task 출력의 문제를 VS Code Problems 패널에 연결하는 실습 프로젝트입니다.
준비 확인
VS Code에서 개별 파일이 아니라 problem-matcher-lab 폴더 전체를 엽니다. Task 기능은 폴더 또는 Workspace를 연 상태에서 사용합니다.

4. 검사 스크립트 만들기

scripts/check-code.js는 src/app.js를 읽고, TODO와 debugger를 발견하면 일정한 형식으로 문제를 출력합니다.

const fs = require("node:fs");

const targetFile = "src/app.js";
const lines = fs.readFileSync(targetFile, "utf8").split(/\r?\n/);

let issueCount = 0;

function report(lineIndex, column, severity, code, message) {
  console.log(
    `${targetFile}:${lineIndex + 1}:${column}: ` +
    `${severity}: [${code}] ${message}`
  );
  issueCount += 1;
}

lines.forEach((line, index) => {
  const todoColumn = line.indexOf("TODO");

  if (todoColumn >= 0) {
    report(
      index,
      todoColumn + 1,
      "warning",
      "LAB001",
      "TODO 주석을 정리하세요."
    );
  }

  const debuggerColumn = line.indexOf("debugger");

  if (debuggerColumn >= 0) {
    report(
      index,
      debuggerColumn + 1,
      "error",
      "LAB002",
      "debugger 문을 제거하세요."
    );
  }
});

if (issueCount === 0) {
  console.log("검사 통과: 문제가 없습니다.");
} else {
  console.log(`검사 완료: ${issueCount}개 문제를 찾았습니다.`);
  process.exitCode = 1;
}

이 스크립트가 출력하는 문제 한 줄의 구조는 다음과 같습니다.

src/app.js:5:4: warning: [LAB001] TODO 주석을 정리하세요.
출력 구성
파일 경로 : 줄 : 열 : 심각도 : 코드와 메시지 순서입니다. 다음 단계에서 이 구조를 정규식으로 분리합니다.

5. Problem Matcher 없이 Task 실행하기

Terminal → Configure Tasks를 선택하고, 새 파일을 만들 때 Create tasks.json file from template → Others를 선택합니다. 생성된 .vscode/tasks.json을 다음처럼 작성합니다.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Check code",
      "type": "process",
      "command": "node",
      "args": ["scripts/check-code.js"],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "problemMatcher": []
    }
  ]
}
  1. Terminal → Run Task를 선택합니다.
  2. Check code를 실행합니다.
  3. 터미널에 문제 두 줄과 검사 결과가 출력되는지 확인합니다.
  4. Problems 패널에는 아직 사용자 정의 문제가 나타나지 않는지 확인합니다.
현재 정상 결과
Task 실행은 실패 상태로 끝나지만 "problemMatcher": []이므로 VS Code는 출력 문장을 문제 위치로 분석하지 않습니다. 오류는 터미널에서만 확인합니다.

6. 사용자 정의 Problem Matcher 추가하기

problemMatcher의 빈 배열을 다음 객체로 교체합니다.

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Check code",
      "type": "process",
      "command": "node",
      "args": ["scripts/check-code.js"],
      "options": {
        "cwd": "${workspaceFolder}"
      },
      "problemMatcher": {
        "owner": "external",
        "fileLocation": [
          "relative",
          "${workspaceFolder}"
        ],
        "source": "lab-check",
        "pattern": {
          "regexp": "^(.*):(\\d+):(\\d+):\\s+(error|warning|info):\\s+\\[([^\\]]+)\\]\\s+(.*)$",
          "file": 1,
          "line": 2,
          "column": 3,
          "severity": 4,
          "code": 5,
          "message": 6
        }
      }
    }
  ]
}
속성역할이번 예제
owner생성한 문제의 소유자external
fileLocation출력된 파일 경로를 해석하는 기준Workspace 기준 상대 경로
sourceProblems 패널에 표시할 문제 출처lab-check
regexpTask 출력 한 줄을 분석하는 정규식파일·줄·열·심각도·코드·메시지 캡처
file~message각 값이 몇 번째 캡처 그룹인지 지정1번부터 6번까지 순서대로 연결

7. 정상 결과 확인하기

  1. Terminal → Run Task → Check code를 다시 실행합니다.
  2. Windows·Linux는 Ctrl + Shift + M, macOS는 Shift + Command + M으로 Problems 패널을 엽니다.
  3. src/app.js 아래에 경고 한 개와 오류 한 개가 표시되는지 확인합니다.
  4. 문제 항목을 선택해 표시된 줄과 열이 실제 TODO와 debugger 위치인지 확인합니다.
정상 결과
  • LAB001: 5번째 줄의 TODO가 warning으로 표시됩니다.
  • LAB002: 6번째 줄의 debugger가 error로 표시됩니다.
  • 문제 출처는 lab-check로 구분됩니다.
  • 편집기와 Problems 패널에서 문제 위치를 확인할 수 있습니다.

8. 문제를 수정하고 다시 검사하기

src/app.js에서 TODO 주석과 debugger; 줄을 삭제합니다.

const userName = "VS Code";
const greeting = `Hello, ${userName}`;

console.log(greeting);
  1. 파일을 저장합니다.
  2. Check code Task를 다시 실행합니다.
  3. 터미널에 검사 통과: 문제가 없습니다.가 표시되는지 확인합니다.
  4. Problems 패널에서 lab-check 문제가 더 이상 남아 있지 않은지 확인합니다.
중요한 습관
코드를 수정한 것만으로 Task 결과가 자동 갱신되는 것은 아닙니다. 검사 Task를 다시 실행해 새 출력으로 문제 상태를 갱신해야 합니다.

9. 정규식과 캡처 그룹 이해하기

이번 정규식은 문제 한 줄을 여섯 부분으로 나눕니다.

^(.*):(\d+):(\d+):\s+(error|warning|info):\s+\[([^\]]+)\]\s+(.*)$
캡처 그룹일치하는 값Problem Matcher 속성
1src/app.js"file": 1
25"line": 2
34"column": 3
4warning"severity": 4
5LAB001"code": 5
6TODO 주석을 정리하세요."message": 6
JSON 안에서는 역슬래시를 두 번 적습니다
정규식 자체의 \d는 tasks.json 문자열에서 \\d로 작성해야 합니다. 역슬래시를 한 번만 적으면 JSON 문자열 또는 정규식이 의도와 다르게 해석될 수 있습니다.

10. 자주 하는 실수와 복구 방법

문제가능한 원인복구 방법
터미널에는 오류가 있지만 Problems가 비어 있음problemMatcher가 빈 배열이거나 정규식 불일치최종 Matcher 객체로 복원하고 출력 한 줄과 정규식을 대조
파일을 찾지 못한다는 표시가 나타남fileLocation과 실제 경로 기준이 다름상대 경로라면 Workspace 기준 설정과 cwd 확인
문제 줄이나 메시지가 엉뚱함캡처 그룹 번호가 잘못 연결됨file·line·column·message 번호를 정규식 괄호 순서와 맞춤
tasks.json에 문법 오류가 생김역슬래시 또는 따옴표 이스케이프 오류제공된 정규식 문자열로 복원하고 Problems 표시 확인
warning이 모두 error로 표시됨severity 캡처 그룹을 연결하지 않음"severity": 4가 있는지 확인
별도 로그 파일의 오류를 읽지 못함Matcher는 실행한 명령의 출력만 분석Task가 끝나기 전에 로그 내용을 표준 출력으로 출력하도록 명령 수정
수정했는데 이전 문제가 계속 보임Task를 다시 실행하지 않음파일 저장 후 같은 검사 Task를 재실행

복구 순서

  1. 터미널에서 실제 출력 한 줄을 그대로 확인합니다.
  2. 출력이 파일:줄:열: 심각도: [코드] 메시지 형식인지 확인합니다.
  3. tasks.json의 정규식과 그룹 번호를 제공된 최종 예제로 되돌립니다.
  4. fileLocation과 options.cwd가 Workspace 기준인지 확인합니다.
  5. Task를 다시 실행하고 Problems 패널을 확인합니다.

11. 직접 따라 하기와 연습 과제

직접 따라 하기 체크리스트

  • problem-matcher-lab 폴더 전체를 VS Code에서 열었다.
  • 검사 스크립트가 일정한 한 줄 형식으로 경고와 오류를 출력했다.
  • problemMatcher: [] 상태에서는 터미널에만 결과가 보이는 것을 확인했다.
  • 사용자 정의 정규식과 캡처 그룹을 tasks.json에 추가했다.
  • Problems 패널에 warning과 error가 각각 표시되는 것을 확인했다.
  • 코드를 수정하고 Task를 다시 실행해 문제를 제거했다.

연습 과제 1 · info 심각도 추가하기

console.log가 있는 줄을 찾아 info 문제로 출력하도록 검사 스크립트를 확장합니다. 정규식은 이미 info를 허용하므로 새 문제의 코드와 메시지만 정합니다.

연습 과제 2 · 파일 하나 더 검사하기

src/helper.js를 만들고 같은 형식으로 문제를 출력합니다. fileLocation을 변경하지 않아도 두 파일을 올바르게 찾는지 확인합니다.

연습 과제 3 · 일부러 패턴을 깨고 복구하기

출력의 warning 앞 공백을 제거하거나 구분 기호를 바꿔 Problems 결과가 사라지는지 확인한 뒤, 출력과 정규식을 다시 같은 형식으로 맞춥니다.

12. 다음 편 예고

커맨드 팔레트 5부 · Watch Task와 Background Problem Matcher
다음 편에서는 파일을 저장할 때마다 계속 실행되는 Watch Task의 시작·종료 상태를 background, beginsPattern, endsPattern으로 추적하는 방법을 초보자용 예제로 이어갑니다.
반응형
이 글이 유용했다면 링크를 공유해 보세요.