zeh/prando

ES6 import error

Closed this issue ยท 10 comments

A TS file such as:

import Prando from 'prando';

const test = new Prando();

Compiled to JS and ran throws:

const test = new prando_1.default();
             ^

TypeError: prando_1.default is not a constructor
    at Object.<anonymous> (/.../dist/prando.test.js:5:14)
    at Module._compile (internal/modules/cjs/loader.js:688:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:699:10)
    at Module.load (internal/modules/cjs/loader.js:598:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:537:12)
    at Function.Module._load (internal/modules/cjs/loader.js:529:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:741:12)
    at startup (internal/bootstrap/node.js:285:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:739:3)

Doing the require method allows construction of a Prando object but breaks all the typing.

Same result in Node versions 8.9.2 and 10.12.0

zeh commented

Sorry I missed this earlier! Checking it this week. Weird as I have it working; might be due to my tsconfig settings.

Do you know if import * as Prando from 'prando'; works?

I'm running into the same issue. When I try import * as Prando from 'prando';, I get the following TypeScript error:

Cannot use 'new' with an expression whose type lacks a call or construct signature..

zeh commented

@jcowman2 @miso440 Do you have a link to any project that causes this error when attempting to import Prando? The reason I'm asking is because I've been unable to replicate it; my own projects that use the package still work with the latest version. I'm thinking this is somehow related to the tsconfig settings, but haven't been able to pinpoint what yet.

@zeh Thanks for looking into this. Here's the branch of my project that's failing.

To replicate, clone + install dependencies, then run npm test. There should be a bunch failing with that same trace.

zeh commented

@jcowman2 Thanks man, I'm taking a look.

zeh commented

Identified the issue, more or less. It's when using TSC directly or, in your case, ts-node. They try resolving to the main file of package.json (the UMD export) rather than the module file (which would be more kosher) then it breaks. The funny thing is, importing the same UMD file through pure JavaScript works fine.

I haven't noticed that before because my standard builds use Webpack or similar packagers, and it works fine there. Apologies.

Still investigating, as it's likely we just need to export the UMD file in a way that is better understood by tsc.

Edit: more investigation: UMD modules with defaults are not properly imported by TypeScript because of this error. Compiling with esModuleInterop makes it possible to properly import Prando from "prando"; but of course requires a change in every project. Trying to see if there's a way to circumvent that during generation. In general it works with the current bundler (Rollup) with exports: named for the umd output, but then it breaks on JavaScript.

zeh commented

@jcowman2 I think I've fixed it. It was missing a synthetic export. I managed to fix in another library of mine with a hack but somehow never realized it was missing in this library.

Anyway, I've published a new release. It shouldn't be breaking anything (old exports are still the same), but since this is somewhat of a big impact change, it's a new major version: 5.0.0.

Trying your repo with

npm install prando@latest --save
npm run test

Works well with the tests you had that were previously broken.

Can you try again?

I've just confirmed, it works in my project now. Thanks so much for the help, @zeh ! ๐ŸŽ‰

zeh commented

Nice! Thank you for the report and the repro!

zeh commented

Closed as this is fixed in v5.0.0.