【问题标题】:How can I convert named imports to default imports in VSCode?如何在 VSCode 中将命名导入转换为默认导入?
【发布时间】:2022-06-17 03:10:14
【问题描述】:

我正在使用 VSCode 并尝试将导入在我的项目中的多个文件中写入的方式更正为更高性能的格式 - VSCode 是否具有可以促进这一点的功能?可以通过内置的查找和替换来完成吗?还是其他 VSCode 功能可以做到这一点?

我得到的导入看起来像这样(substance-ux 是真实模块名称的混淆版本,因为我不想要模块特定的答案):

import { Foo, Bar as BarBar } from '@substance-ux/glyphs';

或许:

import {
  GlyphWithLongName as LongName,
  GlyphWithExtraLongName as ExtraLong
} from '@substance-ux/glyphs';

需要将它转换成这种风格,匹配我们项目中其他地方的导入:

import Foo from '@substance-ux/glyphs/Foo';
import BarBar from '@substance-ux/glyphs/Bar';

或者这个:

import LongName from '@substance-ux/glyphs/GlyphWithLongName';
import ExtraLong from '@substance-ux/glyphs/GlyphWithExtraLongName';

(顺便说一句,'@substance-ux/glyphs/GlyphWithExtraLongName' 之类的文件已经存在,并且包的文档说 @substance-ux/glyphs 模块在导入时会运行大量代码,这会减慢开发构建速度。)

现在,如果我知道我有一种或另一种格式,或者我知道有多少,那么我可以依靠查找和替换,例如我可以使用一些正则表达式(查找:import \{ (.*), (.*) } from '(@substance-ux/glyphs)'; 替换 import $1 from '$3/$1';\nimport $2 from '$3/$2';)和 Find and Replace feature in VSCode

但是,如果我有可变数量的导入,或者混合样式(有些'as'有些不是),如果我尝试一次性完成此操作,我就会完全陷入困境。

我知道snippets 可以使用 TextMate 语法进行正则表达式捕获和一些巧妙的替换,但我认为他们不能处理可变数量的捕获组?或者他们可以吗?

在没有扩展等的 VSCode 中这可能吗?

【问题讨论】:

  • 片段可以处理可变数量的参数 - 我已经回答了一些 SO 问题表明 - 但我认为它们不适用于您的格式。我真的认为您的情况没有非扩展或非脚本解决方案。如果您对此感兴趣,我有一个非常简洁的扩展解决方案。
  • @mark 是,但最好作为答案,这样可以接受它

标签: javascript regex visual-studio-code


【解决方案1】:

片段可以处理可变数量的参数 - 我已经回答了一些 SO 问题表明 - 但我认为它们不适用于您的格式,其中参数已经存在而不是作为参数的一部分输入sn-p。我真的认为您的情况没有非扩展或非脚本解决方案。

使用我编写的扩展程序 Find and Transform,您可以在键绑定或设置中编写 javascript。

这个键绑定 - 在你的 keybindings.json 中 - 会做你想做的事(它也可以是一个设置,以便命令出现在命令面板中):

{
  "key": "alt+f",                 // whatever keybinding you want
  "command": "findInCurrentFile",
  "args": {

    "find": "(import\\s*{\\s*)([^}]+?)(\\s*}\\s*from\\s*')([^']+)';",
    
    "replace": [
      "$${",
      
        "const from = `$4`;",   // capture group 4 from the find
        
        // using capture group 2 from the find regex
        // note backticks around $2 below because it could contain newlines

        "const splitImports = [...`$2`.matchAll(/(\\w+)(?:$|,)|(\\w+)\\s?as\\s?(\\w+)/g)];",
        
        "let str = '';",
        
        "splitImports.forEach((match, index) => { ",

          // don't add a newline if last match
          "let newline = '';",
          "if (index < splitImports.length - 1) newline = '\\n';",
          
          // note double-escapes necessary
          "if (match[1]) str += `import ${match[1]} from \\'${from}/${match[1]}\\';${newline}`;",
          "if (match[2]) str += `import ${match[3]} from \\'${from}/${match[2]}\\';${newline}`;",
        "}); ",
        
        "return str;",
      
      "}$$"
    ],
    
    "isRegex": true,
    // "restrictFind": "line",
  },
  // "when": "editorLangId == javascript"   // if you want it
}

如演示所示,这将适用于整个文件。如果您想对其进行测试或只是让它执行您选择的行,请启用"restrictFind": "line"

【讨论】:

    【解决方案2】:

    我不明白 vscode 程序与您的代码有什么关系。该程序不会主动更改您的代码结构,您必须手动完成:

    你有这个:

    import { Foo, Bar as BarBar } from '@substance-ux/glyphs';
    

    而你想要这个:

    import Foo from '@substance-ux/glyphs/Foo';
    import BarBar from '@substance-ux/glyphs/Bar';
    

    @substance-ux/glyphs 文件内部有多个 named 导出,所以 如果要拆分内容,则需要创建专用文件 导出default,因此创建一个Foo.js 文件,其中export default Foo; 和更多来自@substance-ux/glyphs 的与Foo 相关的所有代码到新文件,或者只是从Foo.js 中导入并重新公开为默认

    新的Foo.js 文件:

    import { Foo } from '@substance-ux/glyphs';
    export default Foo;
    

    新的Bar.js 文件:

    import { Bar } from '@substance-ux/glyphs';
    export default Bar;
    

    您可以按您希望的任何名称导入任何 默认 导出的东西:

    import Banana from '@substance-ux/glyphs/Bar';
    

    但我不明白您为什么要这样做。您没有向我们解释从单个文件导入多个内容有什么不好。摇树?

    【讨论】:

      猜你喜欢
      • 2020-05-12
      • 2018-10-12
      • 2018-09-06
      • 1970-01-01
      • 2022-07-10
      • 2022-06-25
      • 1970-01-01
      • 2022-11-02
      • 2020-01-03
      相关资源
      最近更新 更多