Skip to content
This repository has been archived by the owner on Nov 20, 2023. It is now read-only.

fix(types): Enable plugin to be imported under ES6 #316

Merged
merged 4 commits into from
Oct 1, 2021

Conversation

lobsterkatie
Copy link
Member

@lobsterkatie lobsterkatie commented Sep 30, 2021

Because the webpack plugin is written in vanilla JS (rather than TS), we have a manually-generated type declaration file, where we default-export the SentryCliPlugin class. We also have a file (cjs.js) which is meant to make the plugin play nicely with CommonJS imports. And if the user is indeed using CommonJS imports (const SentryWebpackPlugin = require('@sentry/webpack-plugin')), that all works great.

But if you try to do ES6 imports, the only form which gets you anything besides undefined is import * as SentryWebpackPlugin from '@sentry/webpack-plugin'.* As far as TS is concerned, though, that creates a namespace rather than a class, and so it will refuse to let you call new SentryWebpackPlugin, instead telling you that SentryWebpackPlugin is not contructable. One solution is to use esModuleInterop, but that's gotten us into trouble before and in fact breaks some of our own SDK code.

*The other two options are import SentryCliPlugin as SentryWebpackPlugin from '@sentry/webpack-plugin' and import { default as SentryWebpackPlugin } from '@sentry/webpack-plugin', both of which let you call new on them, but neither of which currently actually gives you anything other than undefined).

The alternative (which is what's done in this PR) is to do two things:

  1. Use the older, more universal exports = ... syntax in our type declaration file rather than our current export default ... syntax (which, according to the TS docs, actually won’t work unless esModuleInterop is set to true). This then necessitates moving the options interface into a namespace for the module.

  2. Explicitly create an export under the name default, so that the two alternatives above actually come up with something rather than being undefined.

This shouldn't affect any current imports, as the first change just moves to an equivalent syntax, and the second change is purely additive.

@lobsterkatie lobsterkatie force-pushed the kmclb-fix-exports-for-default-import branch from a76a01d to a3465f9 Compare September 30, 2021 07:26
Comment on lines +36 to +38
"peerDependencies": {
"@types/webpack": "^4.0.0 || ^5.0.0"
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this. This way we will make everyone install it, even when they are not using TypeScript. Otherwise, we'll warn every time they don't.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning is fine IMO. But, when does one install the webpack plugin and not webpack?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never, but those are types, not webpack itself.

Copy link
Member Author

@lobsterkatie lobsterkatie Oct 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I debated about that. I can't believe we put a man on the moon more than half a century ago and still haven't solved this problem. Either we:

  • make it a hard dependency ( which is what the TS docs would have us do), and plain JS people install a package they don't need, or

  • make it a peer dependency, and plain JS people get warnings which don't apply to them, or

  • make it neither, and TS people get yelled at by their linter and/or compiler unless they just happen to already have the relevant types installed.

Which is the least bad, do we think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one is a no-go for me, and I rather the third over the second although not strongly opinionated against the second one.

  • Why should JS people get warnings related to TS?
  • TS people know they sometimes need to install additional modules for the types, so this shouldn't be a big deal.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also go with 3rd. If you are using TypeScript and Webpack, there's 99,99% chance that you already have those types installed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TS people know they sometimes need to install additional modules for the types, so this shouldn't be a big deal.

Yeah, but that's generally for their own dependencies, not transitive ones. I agree it's not the world's biggest blocker, and people will figure it out, so in this case I'm happy to go with option 3, especially since you're right, @kamilogorek, it's not like webpack is obscure and at least some folks will already have the types. (I'm less convinced it's everyone, though. If you're using our nextjs SDK and don't have any custom webpack config other than what you pass to our plugin, there's no reason you'd already have them.) So I can pull it.

As a general principle, though, and given just how popular TS is, it's still just amazing to me that npm/yarn haven't adapted to what has to be a pretty common situation/problem.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a general principle, though, and given just how popular TS is, it's still just amazing to me that npm/yarn haven't adapted to what has to be a pretty common situation/problem.

Not sure this is only an npm/yarn thing, but also from the npm registry? But yes, there should be a solution to this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is only an npm/yarn thing, but also from the npm registry?

Not sure what you mean.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The npm registry is npmjs.com, and then the npm tool which you use to manage the modules in the registry. Anyways, I haven't dived into the registry and I don't know where the solution should be coming from, just giving my thoughts.

src/cjs.js Show resolved Hide resolved
Comment on lines +36 to +38
"peerDependencies": {
"@types/webpack": "^4.0.0 || ^5.0.0"
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning is fine IMO. But, when does one install the webpack plugin and not webpack?

Copy link
Contributor

@kamilogorek kamilogorek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small Q regarding peerDeps otherwise +1

@kamilogorek
Copy link
Contributor

Feel free to merge it

@lobsterkatie lobsterkatie merged commit f9ef5ce into master Oct 1, 2021
@lobsterkatie lobsterkatie deleted the kmclb-fix-exports-for-default-import branch October 1, 2021 16:59
@lobsterkatie
Copy link
Member Author

So I did remove the peer dependency... and then forgot to push the change before I merged. 🤦🏻‍♀️

It's included as a separate commit here.

@kamilogorek
Copy link
Contributor

correct link eff7c9d

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

Successfully merging this pull request may close these issues.

3 participants