-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
MJS build has different shape than non-MJS build #1513
Comments
This sounds like an issue with the types package ( |
@stephenmathieson The issue is that the type signature changes depending on your bundler (or, what imports the library). Right now, depending on how you use the same module, you may get one of two different behaviors. The types represent only one of those two behaviors. That's not to say the types are correct, but I'd argue that Koa's current configuration makes it hard (if not impossible) to get that right. |
Yes, one CommonJS, one ESM. That is by design (I think 🤔). I disagree that the two should be consistent. CommonJS users don't need I very well may be missing something here, but I still believe this would be resolved if |
The issue is that we're talking about three separate systems, which are independent:
You can be using ESM imports in your code while still using CommonJS (this is extremely common with Webpack and other bundlers). Your bundler may use traditional CommonJS modules and MJS modules simultaneously (as is the case with recent versions of Webpack). This means that the version which gets imported and compiled is not necessarily known. Regardless of what the type definitions say, at this point, Koa may be exposed as a default import or not. There is no way to create type definitions at this point which describe the shape of Koa's exports, since they change depending on the configuration of the system which imports the files (Webpack, directly with Node, etc.) and the Using ESM imports is extremely common even under CommonJS because it enables tree shaking and other features. Because of a change in a project's environment (a version change, dependency changes), regardless of type definitions, Koa can spontaneously stop working because the MJS version might become enabled (or disabled!). Because there is no overlap in the shape of the two versions, it's impossible (without hacks) to write an ESM import of Koa which works under both MJS and CommonJS. Consider a more direct scenario: I decide to write a framework which wraps Koa. It's now impossible for me to (without hacks) write the MJS version first and compile it to CommonJS. This is because if I write While I understand that semantically it makes little sense to have a |
I see, thanks for the explanation. JS is getting out of hand, haha. Let's see what the maintainers want to do about this. |
So I've read and re-read your comment @mattbasta. I am not at all a TS user, but if Off the top of my head, here, untested: module.exports = class Application extends Emitter {
static get default = Application
} Edit: |
@miwnwski That would solve the runtime issue, yes. The types would need to be updated to reflect that also, but that should be trivial. |
I'm using Typescript for my project with Webpack 5 to compile.
Typescript uses the definitions from
@types/koa
, which currently represent the non-MJS build, which has the equivalent ofmodule.exports = class Koa {...}
. This is represented in the TS declaration as the equivalent ofexport = Koa
.The MJS build, however, exports
Koa
asdefault
. The TS definition for this would beexport default Koa
.When importing Koa with
import * as Koa from 'koa';
(which is the only way allowed withoutesModuleInterop
enabled), Typescript believes thatKoa
is the constructor. However, the constructor is actuallyKoa.default
because theimport
statement switches to the MJS build.I currently work around this by doing the following in my code:
Obviously this isn't great, but short of disabling MJS support, it's the best I can do for now.
The underlying issue here is that the MJS support introduced by #1474 was a backwards-incompatible change for folks using an import-aware bundler like Webpack. The mismatch between the type definitions (which are explicit that
import Koa from 'koa';
will not work) and the MJS export (where only the default export is set) causes a problem which can only be detected at runtime or in tests.The fix which seems most apparent to me is two parts:
default
export to the non-MJS buildexport =
export and force folks over to the default export, ensuring that the typechecker will catch these issues immediately rather than at CI/runtime.The text was updated successfully, but these errors were encountered: