VS Code Extension API로 나만의 개발 생산성 도구를 만들어보자
VS Code Extension API를 활용하여 자주 사용하는 React 컴포넌트 템플릿을 자동으로 생성하는 개발 도구를 직접 만들어보는 과정을 통해, 확장 프로그램 개발의 기초를 다지고 개발 생산성을 향상시키는 방법을 알아봅니다.
🚀 VS Code Extension API로 나만의 개발 생산성 도구를 만들어보자
프론트엔드 개발을 하다 보면 반복적인 작업을 자동화하거나, 특정 코드 패턴을 쉽게 삽입하고 싶을 때가 있습니다. VS Code는 강력한 확장 프로그램 생태계를 통해 이러한 요구를 해결할 수 있도록 지원합니다. 이번 글에서는 VS Code Extension API를 활용하여 간단하지만 유용한 개발 생산성 도구를 직접 만들어보는 과정을 통해, 확장 프로그램 개발의 기초를 다지고 자신만의 개발 환경을 더욱 효율적으로 만들어 보겠습니다.
❓ 왜 나만의 개발 도구를 만들어야 할까?
이미 수많은 VS Code 확장 프로그램이 존재하지만, 모든 개발자의 워크플로우와 요구사항을 완벽하게 충족시키지는 못합니다. 특정 프로젝트에서만 사용되는 고유한 코드 패턴, 자주 사용하는 API 스니펫, 혹은 팀 내에서만 공유되는 코드 검사 규칙 등이 있을 수 있습니다. 이러한 경우, 직접 확장 프로그램을 개발하여 이러한 니즈를 충족시키는 것이 가장 효율적인 방법입니다. 이는 단순한 반복 작업 자동화를 넘어, 개발 과정에서 겪는 불편함을 해소하고 궁극적으로 개발 생산성을 크게 향상시킬 수 있습니다.
🛠️ 문제 해결형: 자주 사용하는 컴포넌트 템플릿 자동 삽입 도구 만들기
이번 글에서는 React 개발 시 자주 사용하는 컴포넌트 템플릿을 빠르고 쉽게 삽입할 수 있는 VS Code 확장 프로그램을 만들어 보겠습니다. 예를 들어, 간단한 함수형 컴포넌트나 클래스형 컴포넌트의 기본 구조를 입력하는 데 드는 시간을 절약하고 싶을 때 유용할 것입니다.
1. 확장 프로그램 생성 및 기본 설정
먼저, VS Code Extension Generator를 사용하여 새로운 확장 프로그램 프로젝트를 생성합니다.
1npx -p yo -p generator-code yo code
TypeScript를 선택하고, New Extension (TypeScript)를 선택합니다. 프로젝트 이름은 my-component-generator로 지정하고, npm을 사용하도록 선택합니다. 생성된 프로젝트의 package.json 파일에는 확장 프로그램의 메타데이터와 의존성이 정의됩니다. activationEvents는 확장 프로그램이 활성화될 시점을 정의하는데, 여기서는 onCommand:my-component-generator.createComponent로 설정하여 특정 명령이 실행될 때 활성화되도록 합니다.
2. 명령 실행 및 사용자 입력 받기
src/extension.ts 파일에서 activate 함수 내에 다음과 같이 명령을 등록합니다. 이 명령이 실행되면 사용자로부터 컴포넌트 이름과 타입을 입력받습니다.
1import * as vscode from 'vscode'; 2 3export function activate(context: vscode.ExtensionContext) { 4 let disposable = vscode.commands.registerCommand('my-component-generator.createComponent', async () => { 5 const componentName = await vscode.window.showInputBox({ 6 prompt: '컴포넌트 이름을 입력하세요 (예: MyComponent)', 7 placeHolder: 'ComponentName' 8 }); 9 10 if (!componentName) { 11 vscode.window.showErrorMessage('컴포넌트 이름이 입력되지 않았습니다.'); 12 return; 13 } 14 15 const componentType = await vscode.window.showQuickPick(['Function Component', 'Class Component'], { 16 placeHolder: '컴포넌트 타입을 선택하세요', 17 }); 18 19 if (!componentType) { 20 vscode.window.showErrorMessage('컴포넌트 타입이 선택되지 않았습니다.'); 21 return; 22 } 23 24 // ... 컴포넌트 코드 생성 로직 ... 25 }); 26 27 context.subscriptions.push(disposable); 28} 29 30export function deactivate() {}n``` 31 32`showInputBox`는 텍스트 입력을, `showQuickPick`은 옵션 중에서 선택을 받는 데 사용됩니다. 사용자가 입력을 취소하거나 유효하지 않은 값을 입력했을 경우에 대한 예외 처리도 포함합니다. 33 34#### 3. 컴포넌트 코드 생성 및 삽입 35 36사용자로부터 받은 이름과 타입을 기반으로 실제 컴포넌트 코드를 생성하고, 현재 편집 중인 문서에 삽입합니다. `componentType` 값에 따라 다른 템플릿을 적용할 수 있습니다. 37 38```typescript 39 let componentTemplate = ''; 40 const pascalCaseName = componentName.charAt(0).toUpperCase() + componentName.slice(1); 41 42 if (componentType === 'Function Component') { 43 componentTemplate = `import React from 'react'; 44 45interface ${pascalCaseName}Props {} 46 47const ${pascalCaseName}: React.FC<${pascalCaseName}Props> = (props) => { 48 return ( 49 <div> 50 {/* ${pascalCaseName} Component */} 51 </div> 52 ); 53}; 54 55export default ${pascalCaseName}; 56`; 57 } else { // Class Component 58 componentTemplate = `import React, { Component } from 'react'; 59 60interface ${pascalCaseName}State {} 61 62class ${pascalCaseName} extends Component<{}, ${pascalCaseName}State> { 63 render() { 64 return ( 65 <div> 66 {/* ${pascalCaseName} Component */} 67 </div> 68 ); 69 } 70} 71 72export default ${pascalCaseName}; 73`; 74 } 75 76 const editor = vscode.window.activeTextEditor; 77 if (editor) { 78 editor.edit(editBuilder => { 79 editBuilder.insert(editor.selection.active, componentTemplate); 80 }); 81 vscode.window.showInformationMessage( 82 `${pascalCaseName} ${componentType}가 성공적으로 생성되었습니다!` 83 ); 84 } 85 }); 86 87 context.subscriptions.push(disposable); 88} 89 90export function deactivate() {}n``` 91 92코드 생성 시 `pascalCaseName`과 같이 이름을 파스칼 케이스로 변환하여 일관성을 유지합니다. 생성된 코드는 `editor.edit` 함수를 통해 현재 커서 위치에 삽입됩니다. `vscode.window.showInformationMessage`를 통해 사용자에게 성공 메시지를 전달합니다. 93 94#### 4. `package.json` 설정 및 테스트 95 96`package.json` 파일의 `contributes.commands` 섹션에 방금 등록한 명령을 추가해야 VS Code 명령 팔레트에서 해당 명령을 찾을 수 있습니다. 또한, `main` 필드가 `out/extension.js`를 가리키도록 설정하고, 빌드 스크립트를 추가합니다. 97 98```json 99{ 100 "name": "my-component-generator", 101 "displayName": "My Component Generator", 102 "description": "Generates React component templates.", 103 "version": "0.0.1", 104 "engines": { 105 "vscode": "^1.80.0" // VS Code 버전 명시 106 }, 107 "categories": [ 108 "Other" 109 ], 110 "activationEvents": [ 111 "onCommand:my-component-generator.createComponent" 112 ], 113 "main": "./out/extension.js", 114 "contributes": { 115 "commands": [ 116 { 117 "command": "my-component-generator.createComponent", 118 "title": "Create React Component" 119 } 120 ] 121 }, 122 "scripts": { 123 "vscode:prepublish": "npm run compile", 124 "compile": "tsc -p ./", 125 "watch": "tsc -watch -p ./", 126 "pretest": "npm run compile && npm run lint", 127 "lint": "eslint src --ext ts", 128 "test": "node ./out/test/runTest.js" 129 }, 130 "devDependencies": { 131 "@types/vscode": "^1.80.0", 132 "@types/node": "", 133 "@typescript-eslint/eslint-plugin": "", 134 "@typescript-eslint/parser": "", 135 "eslint": "", 136 "typescript": "" 137 } 138}
npm install을 실행하여 의존성을 설치하고, npm run compile 명령으로 TypeScript 코드를 JavaScript로 컴파일합니다. VS Code에서 F5 키를 눌러 개발 호스트 창을 열고, Create React Component 명령을 실행하여 정상적으로 작동하는지 테스트합니다.
💡 추가적인 생산성 도구 아이디어
이와 같은 방식으로 다양한 생산성 도구를 만들 수 있습니다:
- 코드 스니펫 자동 삽입: 자주 사용하는 API 호출, 특정 로직 패턴 등을 명령어로 삽입
- 파일 구조 생성: 컴포넌트, 페이지 등의 기본 파일 구조 (JS/TS, CSS, Test 파일 등) 자동 생성
- 유닛 테스트 템플릿 생성: Jest, React Testing Library 등을 이용한 기본 테스트 코드 템플릿 생성
- 코드 포맷팅 및 린팅 자동화: 특정 규칙에 맞는 코드 포맷팅 또는 린팅 규칙 위반 시 자동 수정 제안
🚀 마무리
VS Code Extension API를 활용하면 자신만의 개발 워크플로우에 최적화된 도구를 만들어 개발 생산성을 크게 향상시킬 수 있습니다. 이번 글에서 소개한 컴포넌트 템플릿 생성 도구는 시작에 불과하며, VS Code API는 훨씬 더 많은 기능을 제공합니다. 여러분도 직접 아이디어를 구체화하여 자신만의 VS Code 확장 프로그램을 만들어보는 것을 추천합니다.
참고 자료: