Files
2026Technology-Competition/docs/superpowers/specs/implementation-steps/03-phase2.2-eslint-adapter.md
T

2.7 KiB

Step 03 — Phase 2.2: ESLint 适配器

依赖: Step 02
参考设计: §3.3

目标

实现 JavaScript / TypeScript 的 ESLint 适配器,用 eslint npm 包直接检查代码。

前置准备

npm install --save eslint@^9.39.3

新建文件

# 文件 说明
1 src/adapters/eslint.ts ESLintAdapter

src/adapters/eslint.ts

import * as vscode from 'vscode';
import { LinterAdapter, LinterDiagnostic, AdapterResult } from '../types';

export class ESLintAdapter implements LinterAdapter {
  id = 'eslint';
  supportedLanguages = ['javascript', 'typescript'];

  async check(document: vscode.TextDocument, workingDir: string): Promise<AdapterResult> {
    try {
      const code = document.getText();
      const { ESLint } = await import('eslint');
      const eslint = new ESLint({ cwd: workingDir });
      const results = await eslint.lintText(code, { filePath: document.uri.fsPath });

      const diagnostics: LinterDiagnostic[] = [];
      for (const result of results) {
        for (const msg of result.messages) {
          if (!msg.ruleId) { continue; }
          const line = Math.max(0, (msg.line ?? 1) - 1);
          const column = Math.max(0, (msg.column ?? 1) - 1);
          const range = new vscode.Range(line, column, line, column + 1);
          diagnostics.push({
            severity: msg.severity === 2 ? 'error' : msg.severity === 1 ? 'warning' : 'info',
            ruleId: `eslint:${msg.ruleId}`,
            message: msg.message,
            range,
            suggestion: msg.fix ? msg.fix.text : undefined,
          });
        }
      }
      return { diagnostics, status: 'ok' };
    } catch (err) {
      const message = err instanceof Error ? err.message : String(err);
      if (message.includes('Cannot find module')) {
        return { diagnostics: [], status: 'tool-unavailable', errorMessage: 'ESLint 未安装,请执行 npm install eslint' };
      }
      return { diagnostics: [], status: 'execution-failed', errorMessage: message };
    }
  }

  isAvailable(): boolean {
    try {
      require.resolve('eslint');
      return true;
    } catch {
      return false;
    }
  }
}

关键逻辑

  • check(): 使用 ESLint.lintText(code, { filePath }) 直接检查代码文本,支持虚拟文档
  • 将 ESLint 严重级别映射为 error(2) → 'error', warning(1) → 'warning', 0 → 'info'
  • ruleId 加前缀 eslint:,如 eslint:no-unused-vars
  • isAvailable(): 通过 require.resolve 检测 eslint 是否已安装
  • 错误处理:模块未找到 → tool-unavailable,其他错误 → execution-failed

验收

  • 文件创建完成
  • npm run compile 通过
  • npm run lint 通过