简体   繁体   English

在 TypeScript 中从 rrule 包导入 RRule。 获取 SyntaxError:请求的模块“rrule”应为 CommonJS 类型

[英]Importing RRule from rrule package in TypeScript. Getting SyntaxError: The requested module 'rrule' is expected to be of type CommonJS

Update : Tried to create a minimal repro here: https://github.com/aioobe/node-issue-repro .更新:试图在这里创建一个最小的重现: https : //github.com/aioobe/node-issue-repro It's very stripped down obviously, but it exhibits the same error message.显然它非常精简,但它显示了相同的错误消息。

git clone git@github.com:aioobe/node-issue-repro.git
cd node-issue-repro
npm install
npx tsc && node build/index.js

In my TypeScript source code I have the following:在我的 TypeScript 源代码中,我有以下内容:

import { RRule } from 'rrule';

// ...

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

When I run this, I get the following output:当我运行它时,我得到以下输出:

(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..

In my package.json I have在我的package.json我有

{
    ...
    "dependencies": {
        ...
        "rrule": "^2.6.6",
        ...
    },
    ...
    "type": "module"
}

(I need "type": "module" , otherwise I'm running into SyntaxError: Cannot use import statement outside a module .) (我需要"type": "module" ,否则我会SyntaxError: Cannot use import statement outside a module 。)

In my tsconfig.json I have在我的tsconfig.json我有

{
    "compilerOptions": {
        ...
        "allowJs": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        ...
    },
    ...
}

I've noted that in rrule.js thepackage.json does not have "type": "module" , which according to this page means that it should be interpreted as CommonJS.我注意到,在rrule.jspackage.json没有"type": "module" ,它根据该网页的手段,它应该被理解为CommonJS的。

Honestly, I don't really know what this means for me.老实说,我真的不知道这对我来说意味着什么。 I've tried all kinds of syntax variations to include this package in my file (including the one suggested in the error message).我已经尝试了各种语法变体来将这个包包含在我的文件中(包括错误消息中建议的那个)。 I run into various errors, but the syntax posted above is the exact syntax used in the example code in the readme.我遇到了各种错误,但上面发布的语法是自述文件示例代码中使用的确切语法。

I use node version 14.9.0, npm version 6.14.8, typescript version 3.7.2 and ts-node 8.10.2.我使用节点版本 14.9.0、npm 版本 6.14.8、打字稿版本 3.7.2 和 ts-node 8.10.2。 I'm happy to upgrade/downgrade, but I'm running into the same issue with node 12 unfortunately.我很高兴升级/降级,但不幸的是我遇到了与节点 12 相同的问题。

I use lots of other modules the above way without any problem.我以上述方式使用了许多其他模块,没有任何问题。

The "rrule" module seems to declare an invalid index.d.ts . “rrule”模块似乎声明了一个无效的index.d.ts

It says export default RRule;它说export default RRule; but the default export is the entire module.但默认导出是整个模块。

This is simple enough to work around:这很简单,可以解决:

import pkg from "rrule";
const { RRule } = pkg as any;

This behaves equivalently to:这相当于:

import * as pkg from "rrule";
const { RRule } = pkg.default as any;

We need to use any here due to the fact TS thinks this is typeof RRule , even though if you print it you will see it's actually the whole module body.我们需要在此处使用any ,因为 TS 认为这是typeof RRule ,即使您打印它,您也会看到它实际上是整个模块主体。 This is possibly an upstream bug, or a bug with the experimental ESM support.这可能是上游错误,或者是实验性 ESM 支持的错误。

Try replacing the import statement:尝试替换导入语句:

import { RRule } from 'rrule';

with:和:

import pkg from 'rrule';
const {RRule} = (pkg as any);

This worked on Node.js v14.11.0.这适用于 Node.js v14.11.0。


It is actually suggested in the error message that you've received: 它实际上是在您收到的错误消息中建议的:
 (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;

Using commonjs as module code generation type fixes the issue.使用commonjs作为模块代码生成类型修复了这个问题。 Following changes are required:需要进行以下更改:

tsconfig.json配置文件

{
  "compilerOptions": {
    ...,
    "module": "commonjs",
    ...
}

package.json包.json

{
  ...
  "type": "commonjs",
  ...
}

index.ts索引.ts

import { RRule } from "rrule";

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM