【问题标题】:NodeJS import file with the same name as a folderNodeJS导入与文件夹同名的文件
【发布时间】:2020-10-21 15:40:14
【问题描述】:

我有以下文件结构:([] 是文件夹)

[MySQL]
   ConnectionPool.ts
   Connection.ts
MySQL.ts

在我的代码中,我使用 typescript 来开发应用程序,该应用程序将构建为 javascript 用于生产版本。开发版直接从未编译的 typescript 文件中测试,使用 babel 配置如下:

{
    "presets": [
        ["@babel/preset-env", {
            "targets": {
                "node": "current"
            }
        }], 
        "@babel/preset-typescript"
    ],
    "plugins": [
        "@babel/plugin-transform-runtime", 
        [
            "module-resolver",
            {
                "alias": {
                    ... list of some aliases
                }
            }
        ]
    ]
}

我的问题如下,我的大部分导入都是这样的:

import ConnectionPool from 'MySQL/ConnectionPool`

这对我有用,因为当我运行我的开发代码时,编译器正确地将文件扩展名识别为.ts,并且它还正确地将构建版本的文件扩展名识别为.js

但是如果我想导入我的MySQL.ts 文件,我不能这样做,因为我会得到以下错误:Error: Cannot find module './'。如果我在 import 语句中指定文件扩展名,一切正常,但是当我构建代码时,那里将不再有 .ts 文件,所以我会在那里出错。

奇怪的是,在我使用webpack 的前端,我没有收到关于导入不带扩展名的文件的投诉,这些文件的名称与同一目录中的文件夹名称相同。对于这个问题,我有什么解决方案,而不是重命名结构中的文件或文件夹?

【问题讨论】:

  • 我不确定为什么这种模式适合你,但如果你想继续使用它,你需要养成总是写/ 的习惯,如果你想导入文件夹和 . js 如果你想要文件。您也可以尝试为您的文件夹创建别名。

标签: node.js typescript babeljs


【解决方案1】:

将您的文件 MySQL.ts 重命名为 index.ts 并将其移动到文件夹 MySQL

【讨论】:

  • 是的,我知道我可以做到这一点,但我正在寻找一种不涉及重命名我的文件/文件夹的解决方案。
  • NodeJS 将获取与“require”匹配的第一个项目,在这种情况下,它是文件夹,它将在其中搜索索引文件。我真的不知道 webpack 是如何工作的。抱歉,我没有看到你的最后一句话。
【解决方案2】:

与此同时,我通过明确指定.ts 作为文件扩展名解决了我的问题,并在构建代码时使用babel-plugin-transform-rename-import.ts 扩展名替换为.js 扩展名。

我不会接受这个作为正确答案,因为这对我来说太老套了,所以如果出现更好的解决方案,我仍然愿意接受。

【讨论】:

    【解决方案3】:

    我不相信你想要做的事情是可能的,节点会自动包含文件或目录,但如果它们都被称为同一个东西,节点将不知道要导入哪个,它总是更喜欢一个接一个。

    使用import Example from 'example' 将使用节点搜索任何名为 example.js 的文件或名为 example 的带有 index.js 的目录,它只会加载其中一个。

    webpack 正确执行此操作的原因是因为 webpack 永远不会捆绑“目录”,它会将您指定为导入的内容并尝试所有 resolves 扩展名,直到找到一个,然后将其导入文件,所以你永远不会有与 webpack 目录冲突的文件。

    我认为也许一个解决方案是在您的打字稿配置中使用别名,以便您可以使用 import Example from '@example' 并以这种方式区分您的目录和文件。然后,如果您只想加载文件本身,也可以执行import Example from 'example'。但即便如此,我认为这甚至不会起作用,因为一旦它被编译为 javascript,你就会遇到与以前相同的问题,即路径冲突。

    话虽如此,虽然我理解我有点痴迷于命名约定和小事,但我真的认为您不应该将“mysql”存储在“mysql”目录之外,原因有两个。第一个原因是它是那个目录的一部分,这就是那个目录的用途,它包含“mysql”的东西,所以你为什么要把它存储在外面。其次,使用“index.ts”可以与其他开发人员交流一些东西,当我打开一个新项目或目录时,我会立即寻找名为“index.ts”或类似的东西,否则我什至不知道从哪里开始。使用“index.ts”是向任何人传达“此文件就是您要查找的文件,一切从这里开始”的好方法。话虽如此,只需将其称为 index.ts 并将其存储在它所属的位置即可。

    【讨论】:

      【解决方案4】:

      您可以尝试在您的tsconfig.json 中将moduleResolution 设置为classic 策略:

      {
        "compilerOptions": {
          "moduleResolution": "classic"
        }
      }
      

      【讨论】:

        【解决方案5】:

        不幸的是,查看代码,这在您的设置中似乎是不可能的:

        鉴于大多数系统都将遵循 Node 模块解析,我认为您不走运,没有一些手动别名或移动文件。 FWIW,NodeJS 说extensions in import are mandatory

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-06
          • 1970-01-01
          • 2020-01-13
          • 2018-08-09
          • 2011-05-21
          相关资源
          最近更新 更多