最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Importing RRule from rrule package in TypeScript. Getting SyntaxError: The requested module 'rrule'

programmeradmin5浏览0评论

Update: Tried to create a minimal repro here: . It's very stripped down obviously, but it exhibits the same error message.

git clone [email protected]: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:

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! [email protected] 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 [email protected] start-server script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A plete 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

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

(I need "type": "module", otherwise I'm running into SyntaxError: Cannot use import statement outside a module.)

In my tsconfig.json I have

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

I've noted that in rrule.js the package.json does not have "type": "module", which according to this page means that it should be interpreted as 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. I'm happy to upgrade/downgrade, but I'm running into the same issue with node 12 unfortunately.

I use lots of other modules the above way without any problem.

Update: Tried to create a minimal repro here: https://github./aioobe/node-issue-repro. It's very stripped down obviously, but it exhibits the same error message.

git clone [email protected]: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:

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! [email protected] 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 [email protected] start-server script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A plete 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

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

(I need "type": "module", otherwise I'm running into SyntaxError: Cannot use import statement outside a module.)

In my tsconfig.json I have

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

I've noted that in rrule.js the package.json does not have "type": "module", which according to this page means that it should be interpreted as 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. I'm happy to upgrade/downgrade, but I'm running into the same issue with node 12 unfortunately.

I use lots of other modules the above way without any problem.

Share Improve this question edited Sep 16, 2020 at 16:28 aioobe asked Sep 13, 2020 at 16:07 aioobeaioobe 421k114 gold badges828 silver badges839 bronze badges 6
  • Could you please provide minimal environment with issue reproduced, I tried on simple typescript demo environment but couldn't reproduce it on stackblitz: stackblitz./edit/typescript-pwn3lo – Dipen Shah Commented Sep 15, 2020 at 18:01
  • 1 Minimal repro uploaded to gitub repo. git clone [email protected]:aioobe/node-issue-repro.git, cd node-issue-repro, npm install, npx tsc && node build/index.js. – aioobe Commented Sep 15, 2020 at 20:28
  • updating import statement to import RRule from 'rrule'; or import { default as RRule } from 'rrule'; seems to be working. – Dipen Shah Commented Sep 15, 2020 at 20:39
  • Seems to be a known issue on node: github./nodejs/node/issues/32137. Let me know if the fix works for you and I can add it as an answer. – Dipen Shah Commented Sep 15, 2020 at 20:44
  • @DipenShah, error goes away, but it doesn't seem to work. I get undefined for RRule.DAILY for example, and UnhandledPromiseRejectionWarning: TypeError: RRule is not a constructor – aioobe Commented Sep 15, 2020 at 20:48
 |  Show 1 more ment

3 Answers 3

Reset to default 7 +250

The "rrule" module seems to declare an invalid index.d.ts.

It says 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. This is possibly an upstream bug, or a bug with the experimental ESM support.

Using monjs as module code generation type fixes the issue. Following changes are required:

tsconfig.json

{
  "pilerOptions": {
    ...,
    "module": "monjs",
    ...
}

package.json

{
  ...
  "type": "monjs",
  ...
}

index.ts

import { RRule } from "rrule";

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.


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;

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论