Typescript - 导入模块(如果存在)

Yai*_*pro 7 typescript

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

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

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

简单的require不保留类型: 在此输入图像描述

Tad*_*sen 5

这有两个部分:

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

因此,最好的选择可能是向客户端添加一个同名的空模块,因此客户端文件夹type-graphql.ts中调用的文件仅包含:node_modules

export {}
Run Code Online (Sandbox Code Playgroud)

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

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;
Run Code Online (Sandbox Code Playgroud)

在有人指出将文件放在普通 node_modules文件夹中是有问题的之后,我也可以提供一个可能的解决方案。

节点通过从当前文件向上遍历文件夹树来解析模块(不以./或开头/),每个级别都会查看是否存在名为 的文件夹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)
Run Code Online (Sandbox Code Playgroud)

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