【问题标题】:Typescript - Import module if existTypescript - 导入模块(如果存在)
【发布时间】:2019-12-11 19:59:53
【问题描述】:

如果存在模块,如何导入?

我有 2 个项目,客户端和服务器。两者都导入同一个文件。
该文件导入仅安装在服务器项目中的节点模块。客户端没有模块。
因此,从服务器项目打开时,require 必须返回模块 typed
从客户端项目打开时必须返回undefined

下面是客户项目的屏幕截图。 Typescript 无法编译,因为它说它找不到模块。

一个简单的require 不保留类型:

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这有两个部分:

    1. 正式的导入语句必须是无条件的。 import 表示模块必须始终存在。这并不意味着它必须是您真正需要的模块。
    2. 所需的类型是服务器端的module | undefined。但在客户端module 是不可知的。因此,为了允许基于服务器的调用,我们应该允许使用任何字段,例如 {[k:string]:any},并且我们需要能够选择适合我们所在的一侧的字段。

    所以你最好的选择可能是在你的客户端添加一个同名的空模块,所以客户端的node_modules文件夹中的一个名为type-graphql.ts的文件只包含:

    export {}
    

    这样无条件导入将始终有效,客户端将导入此空模块文件,服务器将导入实际库。然后你只需要重新分配变量来考虑可能的接口:

    import * as _TypeGraphQL from 'type-graphql';
    
    // don't check methods on the client side, if we had type definitions on both we could just use that
    type CLIENT_SIDE_INTERFACE = {[k:string]:any};
    // on server side we can check for case that the module is not present.
    type SERVER_SIDE_INTERFACE = typeof _TypeGraphQL | {"ISDUMMY":true}
    
    // if the imported module has our indicator key then we are on the client side
    type THIS_SIDE_INTERFACE = "ISDUMMY" extends (keyof typeof _TypeGraphQL) ? CLIENT_SIDE_INTERFACE : SERVER_SIDE_INTERFACE
    
    const TypeGraphQL: THIS_SIDE_INTERFACE = _TypeGraphQL;
    

    在指出将文件放入正常 node_modules 文件夹是problematic 之后,我也可以提供一个可能的解决方案。

    Node 通过从当前文件向上遍历文件夹树来解析模块(不以 .// 开头),每个级别查看是否有一个名为 node_modules 的文件夹。通常这意味着在您的项目的根目录中有一个包含所有模块的文件夹。但是,您可以在项目中间添加另一个名为 node_modules 的文件夹,那里的任何文件导入都将首先搜索该文件夹。

    因此,对于这样的文件夹结构,您可以将虚拟文件以import * as a from 'test-graphql' 将从稳定文件夹中导入的方式放入项目中:

    root
    - node_modules
    - src
      --- SUBFOLDERS
            - node_modules
              -test-graphql.tsx (dummy code)
            - git-sub-module
              - wrapper.tsx (containing the import code mentioned above)
    

    在这种情况下wrapper.tsx 中的代码将尝试从内部node_modules 导入空模块文件。 只需确保在空模块中添加足够的 cmets 来解释发生了什么巫术 :)

    【讨论】:

    • 感谢您的解释。我现在明白,要导入模块并保持类型,模块目标必须存在,无论它是什么。但是如何在导入状态 from 'type-graphql' 时导入 ISDUMMY 模块?它将在node_modules 中搜索“type-graphql”。如何使其从ISDUMMY 模块导入?
    • 将一个名为type-graphql.tsx 的文件放入客户端的node_modules 文件夹中。编辑答案以澄清。
    • node_modules 中添加文件不是一个稳定的解决方案。如果依赖项被更新/重新安装,模块将被删除。此外,虚拟模块不会在 git 中提交,因此我们必须为每个 git repo 克隆的依赖项重新创建一个虚拟模块。一般来说,永远不要依赖在node_module 文件夹中所做的编辑。
    • 根据导入分辨率,您可以将其放在顶级文件夹中(src 文件夹旁边),或者我已经看到一些将 src 放在分辨率路径上的导入设置,如果是这样的话将其放入 src 的情况也可以。如果您的客户端和服务器位于同一个 git 存储库中,这会使事情复杂化……让我想想……
    • 别担心。客户端和服务器的存储库不同。他们共享一个包含共享类的 git 子模块。谢谢。但我仍然不明白如何从type-graphql 导入目标项目文件。要导入项目文件,导入目标必须以/. 开头,例如./path/to/module。只需type-graphql 直接导入查看 node_modules 即可。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    • 2018-11-01
    • 2012-09-28
    • 1970-01-01
    • 2022-11-26
    • 2015-05-08
    相关资源
    最近更新 更多