我有一个用typescript编写的express服务器,其tsconfig中有"module": "es2020"
。
我还为我的graphql API开发了另一个es2020
模块,仍然是typescript,该模块使用mongose和这样的命名导入:
import { Types } from 'mongoose'
当我用tsc
编译我的graphql模块时,一切都很好。但是使用运行的快递服务器
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;
解决方案#1
import mongoose from 'mongoose'
用mongoose.Types
代替Types
。
但由于tsc
可以处理名为import的猫鼬,我希望也有可能使ts节点能够这样做
解决方案#2
切换到commonjs
,我可以在我的graphql模块中保留导入/导出语法,并将其编译为cjs模块。但我必须在我的express服务器中使用cjs语法,我不想这样做
TL;DR
您所要做的就是从Types中删除大括号。这应该行得通。就像这样:
import Types from 'mongoose'
但名字并不重要。
解释
import Types from 'mongoose'
之所以有效,是因为我们正在导入包的默认导出(这就是为什么我们使用的名称无关紧要)。
然而,当您执行import * as Types from 'mongoose
时,您会告诉JS,您非常希望一切都是原始的。这意味着没有得到默认的导出:
{
"function1": {},
"function2": {}
}
你得到这个:
{
"default": {
"function1": {},
"function2": {}
}
}
所以你也可以做Types.default
,但可能没有那么干净。
StackOverflow的这篇文章表明,我们可以让两者都起作用,但也表明这将是一个可能不应该起作用的破解方法
如果您在使用mono-repo时遇到此错误,请确保您遇到问题的模块具有
"type": "module"
在CCD_ 12中。
Nodejs似乎会默认将包视为commonjs
,并且您需要明确地告诉它您的包是一个模块。