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

fix(types): correct CommonJS export in @fastify/otel typings #30

Closed
wants to merge 1 commit into from

Conversation

bcomnes
Copy link

@bcomnes bcomnes commented Mar 17, 2025

Fixes #24

  • Fix default and named exports in mjs consumers by assigning module.exports and module.exports.FastifyOtelInstrumentation instead of adding static properties to the class. The properties show up as module.exports in mjs and named exports were not working before. Now they are importable in cjs and mjs as one would expect.
  • Added tests for mjs imports.
  • Convert index.d.ts to use export = because this is a type file for a cjs module so we cannot use export foo or export default anywhere without introducing a mismatch between the module system being used in the implementation and types.
  • Move the pure types into a type.d.ts file, where we can use named exports, since exporting them out of a cjs type file is very weird and awkward and requires typeof use by consumers.
  • Moved the fastify mocks from Types from fastify devDependency should not be imported in index.d.ts #32
    to a fastify-mocks.d.ts file to also use named exports but to also discourage their import from consumers, just in case their editor tries to import a fastify type incorrectly out of this module. In general mocking these types seems like it's asking for trouble from a maintenance perspective. Fastify was previously an unlisted peer dependency (presumably because listed peer dependencies can be a nightmare) just as it is in nearly every other fastify plugin. Mocking these types will require ongoing one-off maintenance and will also potentially mask breaking issues as they materialize. Maybe someone more familiar with the deliberate strategy of using unlisted peer dependencies can chime in.

Checklist

Copy link
Member

@metcoder95 metcoder95 left a comment

Choose a reason for hiding this comment

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

can you add some tests for it? Check test/index.test-d.ts

@@ -16,5 +16,4 @@ declare class FastifyOtelInstrumentation<Config extends FastifyOtelInstrumentati
plugin (): (instance: FastifyInstance, opts: FastifyOtelOptions, done: (err?: Error) => void) => void
}

export default FastifyOtelInstrumentation
export { FastifyOtelInstrumentation }
export = FastifyOtelInstrumentation
Copy link
Member

Choose a reason for hiding this comment

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

Good spot!

Is this enough? Should we export the default as other plugins do?

https://github.com/fastify/fastify-redis/blob/713d5019c5bcc7003a0cf42c13cae56551074332/types/index.d.ts#L37-L41

Copy link
Author

@bcomnes bcomnes Mar 17, 2025

Choose a reason for hiding this comment

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

I don't recall spotting other issues on other plugins, but also I import them into register in an fp so maybe I missed the issues. If it's an issue here, then it's also presumably an issue elsewhere. There might be other places where this is addressed, would need to investigate.

Choose a reason for hiding this comment

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

Should we add some tests using eg tsd?

Copy link
Member

Choose a reason for hiding this comment

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

Yes

Copy link
Author

Choose a reason for hiding this comment

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

I mucked around with the tests, and I simply am not familiar enough with TSD or CJS/ESM nuance tests to know how to actually test for this.

@bcomnes
Copy link
Author

bcomnes commented Mar 17, 2025

can you add some tests for it? Check test/index.test-d.ts

Yes, I will add some when I find time on an evening. Anyone feel free to beat me to it.

@@ -16,5 +16,4 @@ declare class FastifyOtelInstrumentation<Config extends FastifyOtelInstrumentati
plugin (): (instance: FastifyInstance, opts: FastifyOtelOptions, done: (err?: Error) => void) => void
}

export default FastifyOtelInstrumentation
export { FastifyOtelInstrumentation }
Copy link
Author

Choose a reason for hiding this comment

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

There is no attempt at named exports afaict:

otel/index.js

Line 410 in 1f850f6

module.exports = FastifyOtelInstrumentation

Copy link
Member

Choose a reason for hiding this comment

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

@bcomnes can you add the named export support?

Copy link
Author

Choose a reason for hiding this comment

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

I added named exports and a default export.

Copy link
Author

Choose a reason for hiding this comment

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

I don't think it's possible to support named mjs exports correctly when assigning module.exports like this. MJS resolves this as { default, and 'module.exports' }.

The typescript typings were exporting using the ESM style exports, but this is a CJS module, so the exports were not resolving correctly. This switches the type export to use `export = ` syntax instead which works for ESM consumers as well as CJS consumers.

Fixes fastify#24

Signed-off-by: Bret Comnes <166301+bcomnes@users.noreply.github.com>
@bcomnes
Copy link
Author

bcomnes commented Apr 6, 2025

  • @mcollina, I don't think named exports are possible here. This module is assigning a class to module.exports with static fields, which works for simulated named exports in cjs const { FastifyOtelInstrumentation } = require('FastifyOtelInstrumentation') along side a cjs style default export const FastifyOtelInstrumentation = require('FastifyOtelInstrumentation'), but in mjs this just resolves to { default, 'module.exports' }, wherein only the default export works, and none of the desired named fields works.
  • The types in this module are broken for mjs consumers, because this is a cjs module exporting types as if it were an esm module. Let's fix that!
  • This situation is now worse since chore(types): Vendor in FastifyInstance type #35 has added additional esm style type exports.
  • I've updated the additional type exports as best as I understand, but in general, the circular references and almost named exports really confuses everything.

Any suggestions on how to test this?

@bcomnes
Copy link
Author

bcomnes commented Apr 6, 2025

I got the named exports working with the top level class. I'll send an alternative request in shortly.

@bcomnes
Copy link
Author

bcomnes commented Apr 7, 2025

Closing this PR out in favor of https://github.com/fastify/otel/pull/43/files

@bcomnes bcomnes closed this Apr 7, 2025
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 this pull request may close these issues.

Typescript import example
5 participants