cari

Rumah  >  Soal Jawab  >  teks badan

Tambahkan pengisytiharan import jika fungsi pembantu belum diimport: Penyelesaian dipertingkat dengan pembetulan peraturan ESLint tersuai

Saya mempunyai kes penggunaan di mana saya ingin menggantikan panggilan fungsi berubah-ubah, khususnya teks pada foo.value.toString() 来使用辅助函数 getStringValue(foo) 。如果我找到它,我可以使用修复程序替换 CallExpression nod, jadi pembetulan peraturan saya pada masa ini kelihatan seperti ini:

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

Masalah dengan membetulkan ralat ini secara automatik dengan cara ini ialah getStringValue mungkin telah diimport ke dalam fail atau tidak. Saya mahu pembetulan ini mempunyai tingkah laku berikut:

  1. Jika fungsi sudah diimport ke dalam fail, tidak perlu melakukan apa-apa lagi.
  2. Jika fungsi tidak diimport, tetapi modul fail yang terkandung di dalamnya diimport, tambahkan fungsi ini pada import modul.
  3. Jika fungsi mahupun modul fail yang mengandunginya tidak diimport, import modul bersama-sama dengan fungsi tersebut.

Setakat yang saya faham daripada dokumentasi, tiada cara mudah untuk melakukan ini menggunakan fixercontext 对象访问根 ESTree 节点。最接近的是 SourceCode.getText(), yang bermaksud saya perlu menghuraikan teks sumber untuk menghuraikan import - Saya lebih suka berinteraksi dengan keseluruhan AST secara langsung. Apakah cara terbaik untuk melaksanakan proses import automatik ini?

P粉312195700P粉312195700244 hari yang lalu332

membalas semua(2)saya akan balas

  • P粉596161915

    P粉5961619152024-03-29 00:56:42

    Jika anda ingin menjadi sedikit tidak selamat di sini, anda boleh menganggap bahawa pengguna tidak mentakrifkan semula fungsi getStringValue secara setempat dalam fail mereka (biasanya andaian selamat jika anda memiliki pangkalan kod yang digunakan oleh peraturan ini).

    Dalam kes ini, cara terbaik ialah menggunakan pemilih untuk menyemak import, contohnya:

    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;
              },
            });
          },
        };
      },
    };

    balas
    0
  • P粉098979048

    P粉0989790482024-03-29 00:43:02

    Ternyata, ada cara mudah untuk melakukannya dari context 对象中提取 AST 根节点。它位于 context.getSourceCode().ast. Saya menulis semula pembetulan saya dengan logik berikut:

    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
    }
    

    balas
    0
  • Batalbalas