从 TypeScript 中的 rrule 包导入 RRule。获取语​​法错误:请求的模块“rrule”预计为 CommonJS 类型

aio*_*obe 5 javascript import module rrule typescript

更新:尝试在这里创建一个最小的重现: https: //github.com/aioobe/node-issue-repro。显然它非常精简,但它显示了相同的错误消息。

git clone git@github.com:aioobe/node-issue-repro.git
cd node-issue-repro
npm install
npx tsc && node build/index.js
Run Code Online (Sandbox Code Playgroud)

在我的 TypeScript 源代码中,我有以下内容:

import { RRule } from 'rrule';

// ...

const oddDays = new RRule({
    freq: RRule.DAILY,
    bymonthday: [1, 3, 5]
});
Run Code Online (Sandbox Code Playgroud)

当我运行它时,我得到以下输出:

(node:31434) ExperimentalWarning: The Node.js specifier resolution in ESM is experimental.
file:///home/aioobe/projects/test/server/database/storage.ts:10
import { RRule } from 'rrule';
         ^^^^^
SyntaxError: The requested module 'rrule' is expected to be of type CommonJS, which does not support named exports. CommonJS modules can be imported by importing the default export.
For example:
import pkg from 'rrule';
const { RRule } = pkg;
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:98:21)
    at ModuleJob.run (internal/modules/esm/module_job.js:137:5)
    at Loader.import (internal/modules/esm/loader.js:165:24)
    at Object.loadESM (internal/process/esm_loader.js:68:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! daily-challenge@0.1.0 start-server: `cross-env NODE_ENV=development node --loader ts-node/esm --es-module-specifier-resolution=node server/server.ts`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the daily-challenge@0.1.0 start-server script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/aioobe/.npm/_logs/2020-09-13T15_53_32_162Z-debug.log
npm run start-server exited with code 1
--> Sending SIGTERM to other processes..
Run Code Online (Sandbox Code Playgroud)

在我的package.json我有

{
    ...
    "dependencies": {
        ...
        "rrule": "^2.6.6",
        ...
    },
    ...
    "type": "module"
}
Run Code Online (Sandbox Code Playgroud)

(我需要"type": "module",否则我会遇到SyntaxError: Cannot use import statement outside a module。)

在我的tsconfig.json我有

{
    "compilerOptions": {
        ...
        "allowJs": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        ...
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

我注意到在rrule.js中没有,根据此页面package.json,这意味着应该被解释为 CommonJS。"type": "module"

老实说,我真的不知道这对我来说意味着什么。我尝试了各种语法变体以将此包包含在我的文件中(包括错误消息中建议的语法变体)。我遇到了各种错误,但上面发布的语法与自述文件中的示例代码中使用的语法完全相同。

我使用节点版本 14.9.0、npm 版本 6.14.8、typescript 版本 3.7.2 和 ts-node 8.10.2。我很高兴升级/降级,但不幸的是我在节点 12 上遇到了同样的问题。

我按照上述方式使用了很多其他模块,没有任何问题。

Bre*_*loy 6

“rrule”模块似乎声明了一个 invalid index.d.ts.

它说export default RRule;但默认导出是整个模块。

这很简单,可以解决:

import pkg from "rrule";
const { RRule } = pkg as any;
Run Code Online (Sandbox Code Playgroud)

这相当于:

import * as pkg from "rrule";
const { RRule } = pkg.default as any;
Run Code Online (Sandbox Code Playgroud)

我们需要any在这里使用,因为 TS 认为这是typeof RRule,即使你打印它,你会看到它实际上是整个模块主体。这可能是上游错误,或者是实验性 ESM 支持的错误。