Importdeklaration hinzufügen, wenn die Hilfsfunktion noch nicht importiert ist: Erweiterte Lösung mit Korrektur benutzerdefinierter ESLint-Regeln
P粉312195700
P粉312195700 2024-03-28 09:26:00
0
2
327

Ich habe einen Anwendungsfall, in dem ich variable Funktionsaufrufe ersetzen möchte, insbesondere Text auf foo.value.toString() 来使用辅助函数 getStringValue(foo) 。如果我找到它,我可以使用修复程序替换 CallExpression Knoten, daher sieht meine Regelkorrektur derzeit so aus:

fixer => fixer.replaceText(node, `getStringValue(${identifierNode.getText()})`);

Das Problem bei der automatischen Behebung dieses Fehlers auf diese Weise besteht darin, dass getStringValue möglicherweise in die Datei importiert wurde oder nicht. Ich möchte, dass sich dieser Fix wie folgt verhält:

  1. Wenn die Funktion bereits in die Datei importiert ist, müssen Sie nichts weiter tun.
  2. Wenn die Funktion nicht importiert wird, aber das darin enthaltene Dateimodul importiert wird, fügen Sie diese Funktion zu den Importen des Moduls hinzu.
  3. Wenn weder die Funktion noch das enthaltende Dateimodul importiert werden, wird das Modul zusammen mit der Funktion importiert.

Soweit ich der Dokumentation entnehme, gibt es keine einfache Möglichkeit, dies mit fixercontext 对象访问根 ESTree 节点。最接近的是 SourceCode.getText() zu tun, was bedeutet, dass ich den Quelltext analysieren muss, um den Import zu analysieren – ich würde lieber direkt mit dem gesamten AST interagieren. Wie lässt sich dieser automatisierte Importvorgang am besten durchführen?

P粉312195700
P粉312195700

Antworte allen(2)
P粉596161915

如果您想在这里稍微不安全,您可以假设用户没有在其文件中本地重新定义 getStringValue 函数(如果您拥有此规则所适用的代码库,通常是一个安全的假设)。

在这种情况下,最好的方法是使用选择器来检查导入,例如:

module.exports = {
  create(context) {
    let hasImport = false;
    let lastImport = null;
    return {
      ImportDeclaration(node) {
        lastImport = node;
        if (isImportICareAbout(node)) {
          hasImport = true;
        }
      },
      "My Selector For Other Linting Logic"(node) {
        // ...
        context.report({
          messageId: "myReport",
          fix(fixer) {
            const fixes = [
              fixer.replaceText(node, `getStringValue(${identifierNode.name})`),
            ];
            if (!hasImport) {
              const newImport = 'import { getStringValue } from "module";';
              if (lastImport) {
                // insert after the last import decl
                fixes.push(fixer.insertTextBefore(lastImport, newImport));
              } else {
                // insert at the start of the file
                fixes.push(fixer.insertTextAfterRange([0, 0], newImport));
              }
            }
            return fixes;
          },
        });
      },
    };
  },
};
P粉098979048

事实证明,有一种简单的方法可以从 context 对象中提取 AST 根节点。它位于 context.getSourceCode().ast。我用以下逻辑重写了我的修复程序:

fixer => {
  fixer.replaceText(node, `getStringValue(${identifierNode.getText()})`);
  const body = context.getSourceCode().ast;
  const importDeclarations = body.filter(statement => statement.type === AST_NODE_TYPES.ImportDeclaration);
  ... // Check if the declaration has the import and add the appropriate imports if necessary
}
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage