Codemod с jscodeshift - убрать запятую из импорта

Я пытаюсь написать небольшой код для рефакторинга части кода. Считайте, что у меня что-то вроде этого:

import { mod1, mod2, mod3 } from 'package1'
import localMod from 'package2'

и я хотел изменить это на:

import { mod1, mod3 } from 'package1'
import * as mod2 from 'new-package'
import localMod from 'package2'

В качестве первого шага я пытаюсь удалить mod2 из первой строки импорта, которую я успешно выполнил, но я не могу удалить запятую после mod1.

Мой фрагмент кода пока выглядит так:

module.exports = function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  const reactApolloImports = root
    .find(j.ImportDeclaration)
    .filter(nodepath => nodepath.value.source.value === "package1")
    .find(j.Identifier)
    .forEach(nodepath => {
      if (nodepath.name === "imported" && nodepath.node.name === "mod2") {
        j(nodepath).remove();
      }
    });

  return root.toSource();
};

Пожалуйста помоги.

2 ответа

Вместо поиска и удаления j.Identifier внутри j.ImportDeclaration, найдите их родительские узлы j.ImportSpecifierвыражение вместо этого. Если вы удалите их, все будет в порядке.

Понятнее, если вставить свой import { mod1, mod2, mod3 } from 'package1'в AST Explorer.

Код:

module.exports = function transformer(file, api) {
  const j = api.jscodeshift;
  const root = j(file.source);

  const reactApolloImports = root
    .find(j.ImportDeclaration)
    .filter(impDecNodePath => impDecNodePath.value.source.value === "package1")
    .forEach(impDecNodePathFiltered => {
      j(impDecNodePathFiltered)
        // find ImportSpecifier here instead of Identifier
        .find(j.ImportSpecifier)
        .forEach(impSpecNodePath => {
          if (impSpecNodePath.node.imported.name === "mod2") {
            j(impSpecNodePath).remove();
          }
        });
    });

  return root.toSource();
};

Изменен вывод:

import { mod1, mod3 } from 'package1';
import localMod from 'package2'

Надеюсь, это поможет.

Для этой цели вы можете использовать преобразователь кода вывода , это значительно упростит задачу:

Вот плагин, который вам нужен, это Replacer:

      export const replace = () => ({
    'import {parse, compare, transform} from "putout"': `{
        import {parse, transform} from 'putout';
        import compare from '@putout/compare';
    }`,
}),

Также мы будем использовать плагин @ putout / plugin-remove-nested-blocks для удаления дополнительных блоков:

      const replaceImports = {
    report: () => '',
    replace: () => ({
        'import {parse, compare, transform} from "putout"': `{
            import {parse, transform} from 'putout';
            import compare from '@putout/compare';
        }`,
    }),
};

const source = `
    import {parse, compare, transform} from 'putout';
`;

const {code} = putout(source, {
    plugins: [
        ['replaceImports', replaceImports],
        'remove-nested-blocks',
    ],
});

Результат будет:

      import {parse, transform} from 'putout';
import compare from '@putout/compare';

Вот как это выглядит на вашем примере (без remove-nested-blocks применяемый):

Основное преимущество - инкапсуляция работы с AST так что вы можете делать больше вещей быстрее и проще.

Другие вопросы по тегам