sindresorhus / p-queue

Promise queue with concurrency control
MIT License
3.45k stars 185 forks source link

Usage with ESM in NodeJS is unintuitive #127

Closed lynxtaa closed 3 years ago

lynxtaa commented 3 years ago

Thanks for this awesome library! From April 2021 all stable Node.js versions support ESM. So I've added "type": "module" to package.json and tried to create a queue:

import PQueue from 'p-queue'
const queue = new PQueue() // TypeError: PQueue is not a constructor
import { default as PQueue } from 'p-queue'
const queue = new PQueue() // TypeError: PQueue is not a constructor
import { default as PQueue } from 'p-queue'
const queue = new PQueue.default() // Works

Is this expected? It looks very unintuitive and also doesn't work with Typescript (Property 'default' does not exist on type 'typeof PQueue'.ts(2339))

lynxtaa commented 3 years ago

Oh, after further investigation I think it's a tsc/NodeJS issue

f1yn commented 3 years ago

What does your tsconfig look like?

lynxtaa commented 3 years ago

@f1yn I'm testing it without typescript, using ESM in NodeJS:

// package.json
{
  "type": "module",
  "dependencies": {
    "p-queue": "^6.6.2"
  }
}
// index.js
import { default as PQueue } from 'p-queue'
const queue = new PQueue.default() // Works

But I think this behavior is expected when using NodeJS. Maybe consider publishing ESM and CJS versions?

Benedikt1992 commented 3 years ago

@f1yn I am running into the same problem. My tsconfig looks like:

{
  "include": [
    "./src/**/*"
  ],
  "compilerOptions": {
    "outDir": "./dist",

    "target": "ES2020",                                /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
    "module": "es2020",                           /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
    "allowJs": true,                             /* Allow javascript files to be compiled. */
    "sourceMap": true,                           /* Generates corresponding '.map' file. */
    "strict": true,                                 /* Enable all strict type-checking options. */
    "moduleResolution": "node",                  /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    "baseUrl": "./",                             /* Base directory to resolve non-absolute module names. */
    "esModuleInterop": true,                        /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    "skipLibCheck": true,                           /* Skip type checking of declaration files. */
    "forceConsistentCasingInFileNames": true        /* Disallow inconsistently-cased references to the same file. */
  }
}