【问题标题】:Codemod with jscodeshift - remove comma from import带有 jscodeshift 的 Codemod - 从导入中删除逗号
【发布时间】:2019-09-03 02:36:07
【问题描述】:

我正在尝试编写一个小的 codemod 来重构一些代码。考虑一下我有这样的东西:

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 之后的逗号。

到目前为止,我的代码 sn-p 如下所示:

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

请帮忙。

【问题讨论】:

    标签: javascript reactjs jscodeshift codemod


    【解决方案1】:

    不是在j.ImportDeclaration 中搜索和删除j.Identifier,而是通过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'
    

    希望,它会有所帮助。

    【讨论】:

      【解决方案2】:

      您可以为此使用putout 代码转换器,它使事情变得更容易:

      这是你需要的插件,它是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 封装工作,因此您可以更快、更简单地完成更多事情。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-22
        • 2011-04-24
        • 1970-01-01
        • 2013-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多