Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Runtime errors if compiled with "esModuleInterop": false #88

Closed
JustinBeckwith opened this issue May 16, 2019 · 5 comments
Closed

Runtime errors if compiled with "esModuleInterop": false #88

JustinBeckwith opened this issue May 16, 2019 · 5 comments

Comments

@JustinBeckwith
Copy link

Thanks for the lovely library! With version 0.17.0, we noticed that our tests suddenly weren't passing:
googleapis/nodejs-pubsub#591

Using TypeScript, everything compiles fine - then we'd get this at runtime:

const iss = is_1.default.string('👋');
                         ^

TypeError: Cannot read property 'string' of undefined
    at Object.<anonymous> (/Users/beckwith/Code/isbroke/build/src/index.js:4:26)
    at Module._compile (internal/modules/cjs/loader.js:816:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
    at Module.load (internal/modules/cjs/loader.js:685:32)
    at Function.Module._load (internal/modules/cjs/loader.js:620:12)
    at Function.Module.runMain (internal/modules/cjs/loader.js:877:12)
    at internal/main/run_main_module.js:21:11

I have a minimal repo here:
https://github.com/JustinBeckwith/is-broke

Just clone, npm install, and npm start to see the error. One thing to note - we do not have esModuleInterop enabled in our tsconfig. If I set that to true - everything does seem to work.

We found that setting esModuleInterop in our modules could have downstream effects for other users (like this case), so we keep it off. I noticed that your base level tsconfig enables both synthetic default imports and es module interop:
https://github.com/sindresorhus/tsconfig/blob/master/tsconfig.json#L9

TL;DR: I think the answer here is to disable esModuleInterop as a default configuration for your TypeScript modules. Could be wrong 🤷‍♂

@sindresorhus
Copy link
Owner

I have a feeling this was the cause: 28913ca

// @bfred-it

@fregante
Copy link
Contributor

fregante commented May 16, 2019

Double-checked, these two are not equivalent since we're overriding module.exports

  module.exports = is;
- module.exports.default = is;
+ exports.default = is;

oops

Edit: wrong

I have a feeling this was the cause: 28913ca

The output is the same (its CJS export is is with a default property) so I doubt it's the cause: #84

- exports.default = is;
  module.exports = is;
+ exports.default = is;
- module.exports.default = is;

The export should probably be updated to use export = is anyway

@fregante
Copy link
Contributor

fregante commented May 18, 2019

The point of esModuleInterop is to allow you to import CJS modules with import from

If you disable that option, you can’t expect to use CJS modules with import from

@JustinBeckwith
Copy link
Author

That is true :) The issue here is that esModuleInterop has side effects for consumers of the module. If you're building an end user application, it's great. But for libraries, it propagates in a way that makes the module unusable for users who don't have esModuleInterop enabled. We went through the same thing with our modules, and had to roll it back because there was no way to guess what users had set up in their tsconfig.

@JustinBeckwith
Copy link
Author

Thanks for the fix folks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants