未找到命名的导出“类型”。请求的模块“mongoose”是一个 CommonJS 模块,它可能不支持所有 module.exports 作为命名导出

Neg*_*oro 32 javascript mongoose commonjs typescript ecmascript-2020

我有一个用 typescript 编写的 Express 服务器,并"module": "es2020"在其 tsconfig.xml 中。

我还es2020为我的 graphql API 开发了另一个模块,仍然是 typescript,这个模块使用 mongoose 和这样的命名导入:

import { Types } from 'mongoose'
Run Code Online (Sandbox Code Playgroud)

当我用 编译我的 graphql 模块时,一切正常tsc。但是运行的快递服务器

nodemon --watch './**/*.ts' --exec 'node --experimental-specifier-resolution=node --loader ts-node/esm' src/index.ts

无法处理名为 import 的猫鼬。

import { Types } from 'mongoose';
         ^^^^^
SyntaxError: Named export 'Types' not found. The requested module 'mongoose' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'mongoose';
const { Types } = pkg;
Run Code Online (Sandbox Code Playgroud)

解决方案#1

import { Types } from 'mongoose';
         ^^^^^
SyntaxError: Named export 'Types' not found. The requested module 'mongoose' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'mongoose';
const { Types } = pkg;
Run Code Online (Sandbox Code Playgroud)

并替换Typesmongoose.Types.

但由于tsc可以处理名为 import 的 mongoose,我希望 ts-node 也能够这样做。

解决方案#2

切换到commonjs,我可以将导入/导出语法保留在我的 graphql 模块中并将其编译为 cjs 模块。但我必须在我的 Express 服务器中使用 cjs 语法,但我不想这样做。

小智 27

长话短说

您所要做的就是从类型中删除花括号。那应该有效。像这样:

import Types from 'mongoose'
Run Code Online (Sandbox Code Playgroud)

但名字并不重要。

解释

import Types from 'mongoose'之所以有效,是因为我们正在导入包的默认导出(这就是为什么我们使用的名称并不重要)。

然而,当你这样做时,import * as Types from 'mongoose你告诉 JS 你真的想要一切,因为它是原始的。这意味着不是获取默认导出:

import Types from 'mongoose'
Run Code Online (Sandbox Code Playgroud)

你得到这个:

{
    "function1": {},
    "function2": {}
}
Run Code Online (Sandbox Code Playgroud)

所以你也可以这样做,Types.default但这可能不那么干净。

这篇 StackOverflow 文章表明我们可以让这两种方法都工作,但也表明这将是一个可能行不通的黑客解决方法

  • 导致问题出现在node_modules(即外部库)内的导入语句是什么? (4认同)

Zuz*_*zEL 6

如果您在使用 mono-repo 时遇到此错误,请确保您遇到问题的模块已安装

"type": "module" 
Run Code Online (Sandbox Code Playgroud)

package.json

看来 Nodejs 会commonjs默认认为包是一个模块,你需要明确地告诉它你的包是一个模块。