Typescript问题记录:无法找到模块 XXX

背景

引入 npm 依赖包时,明明这个包定义了相关的 types 文件,为什么引入时还是提示「无法找到模块 XXX」?例如,该依赖包的 package.json 信息如下:

json 复制代码
{
  "name": "my-module",
  "exports": {
    ".": "./main.js",
    "./feature": "./lib/feature.js"
  },
  "types": "./lib/feature.js"
}

这里有可能是这个依赖包定义 types 文件有问题,如果该依赖包所在项目中的 package.json 文件中设置了 exports 属性,将不会读取外层的 types 属性。

这种情况下,你注意查看详细错误,会有这么一段话:

There are types at 'XXX/types/index.d.ts', but this result could not be resolved when respecting package.json "exports". The 'xxx' library may need to update its package.json or typings.

从以上提示可以看出跟 package.json 中的 exports 有关。

exports

exports 具体是做什么用的呢?

exports 字段在 package.json 文件中用于定义模块的导出方式。这是 Node.js 中的一个新特性,用于替代 main 字段,提供更加灵活的模块导出方式。

exports 字段可以定义一个对象,对象的键是导出模块的名称,值是模块的实际文件路径。这样,当其他模块尝试导入该模块时,就会根据 exports 字段的定义来确定实际导入哪个文件。

例如,你可以在 package.json 文件中这样定义 exports 字段:

json 复制代码
{
  "name": "my-module",
  "exports": {
    ".": "./main.js",
    "./feature": "./lib/feature.js"
  }
}

在这个例子中,如果其他模块尝试导入 my-module,那么实际上会导入 main.js 文件。如果尝试导入 my-module/feature,那么实际上会导入 lib/feature.js 文件。

这样,你就可以更加灵活地控制模块的导出方式,而不仅仅是通过 main 字段指定一个入口文件。

解决方案

如果依赖包中通过 exports 定义导出方式,在 typescript 中如何指定类型定义文件呢?

在 TypeScript 中,你可以使用 typestypings 字段在 package.json 文件中指定类型定义文件的路径。这个文件通常是一个 .d.ts 文件,包含了模块的类型定义。

例如,可以这样设置:

json 复制代码
{
  "name": "my-module",
  "main": "./dist/main.js",
  "types": "./dist/main.d.ts",
  "exports": {
    ".": {
      "import": "./dist/main.js",
      "require": "./dist/main.cjs",
      "types": "./dist/main.d.ts"
    },
    "./feature": {
      "import": "./dist/feature.js",
      "require": "./dist/feature.cjs",
      "types": "./dist/feature.d.ts"
    }
  }
}

在这个例子中,types 字段指定了主模块的类型定义文件的路径,而 exports 字段中的每个导出都有一个对应的 types 字段,指定了该导出的类型定义文件的路径。

这样,当其他 TypeScript 模块尝试导入 my-modulemy-module/feature 时,TypeScript 就会根据这些 types 字段找到对应的类型定义文件,以获取模块的类型信息。

这样设置后,再引入这个依赖包就不会提示「无法找到模块 XXX」。

当然,如果没有特殊需要,也可以不使用 exports 字段,直接设置 maintypes 就好。

相关推荐
陈随易42 分钟前
在Finch用了62亿词元,我认为这是新一代Agent工具之神
前端·人工智能·后端
水域安全老周1 小时前
水趣钓鱼救生衣专利拆解:两级锁紧如何解决落水人衣分离
java·前端·网络
计算机魔术师2 小时前
Anthropic CEO突然喊踩刹车,OpenAI罕见力挺:AI这辆车不能只踩油门了
前端
wing982 小时前
从codex转战workbuddy使用一周的感受
前端·人工智能·后端
EatFan2 小时前
Java接入支付宝 JSAPI 支付保姆教程(二):流程讲解与前后端代码讲解
前端·spring boot·后端·微信小程序·小程序·uni-app
梦想平凡2 小时前
百游棋牌源代码开发搭建教程(五):房间创建、座位分配与请求幂等实现
前端·javascript·数据库·源代码管理
IT_陈寒3 小时前
Redis的Set操作居然能把我的服务整挂了?
前端·人工智能·后端
计算机魔术师3 小时前
Suno 发布 v6 音乐模型,推出 v6、v6-wild、v6-mini 三个版本
前端
whyweplay4 小时前
elpis : DSL动态组件学习
前端
用户921080262864 小时前
前端 Vue 专栏 06:异步更新机制、任务队列与 nextTick
前端