-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Load codegen.ts in ESM projects #9086
Conversation
🦋 Changeset detectedLatest commit: f010b06 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
🚀 Snapshot Release (
|
Package | Version | Info |
---|---|---|
@graphql-cli/codegen |
3.0.4-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/cli |
3.2.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/visitor-plugin-common |
3.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/typescript-document-nodes |
3.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/gql-tag-operations |
2.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/typescript-operations |
3.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/typescript-resolvers |
3.1.1-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/typed-document-node |
3.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/typescript |
3.0.2-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/client-preset |
2.1.1-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
@graphql-codegen/graphql-modules-preset |
3.1.1-alpha-20230307110723-f010b0664 |
npm ↗︎ unpkg ↗︎ |
💻 Website PreviewThe latest changes are available as preview in: https://5d1dbded.graphql-code-generator.pages.dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your code is very clean and easy to read - this looks great!
About the ESM detection, maybe I am too naive, but couldn't we just look for the import
keyword in the config? We can use a regex for increased accuracy, something like import (.* from|"|')
.
Also, a test case for this would be great.
Hmm, I'm not sure. You can have a TypeScript file with ESM syntax that technically is a CommonJS and can be required by ts-node. Notice that this bug only occurred with |
Yes, you're right. But, it might make sense to immediately drop to In future steps we might even drop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great to me! I like that we dropped the cosmiconfig-typescript-loader especially.
We can go ahead and merge after the CI's all green.
// #8437: conflict with `graphql-config` also using TypeScriptLoader(), causing a double `ts-node` register. | ||
const tsLoader = TypeScriptLoader({ transpileOnly: true }); | ||
return tsLoader(filepath, content); | ||
const jiti = require('jiti')(__filename, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use import
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also do we bundle codegen cli to both cjs and Esm? If yes __filename will be not exist in esm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah right. We do bundle to both. What's the best way to deal with it? Something like this:
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@enisdenjo could we add banner with bob? Or should we bundle to Esm only instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@beerose yeah but we need to add it only to ESM build 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@saihaj, do you have any thoughts on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think script is fine for simplicity. We do similar thing too for binary. Ideally bob
should have some hooks
that we can use to call scripts as needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we do the same thing here?
if there is no other workaround..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, so it looks like we can workaround it by not providing __filename at all — jiti resolves it to process.cwd()
, which I guess it's correct? https://github.com/unjs/jiti/blob/main/src/jiti.ts#L101
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, the CI passes 😅
@enisdenjo I think we can remove ts-node too now? |
Yes sir! I think it was only necessary for cosmiconf. |
Is there any documentation that needs to be updated regarding this? |
I think we are good here. |
3dbaac7
to
2b36f09
Compare
Follow up PR: #9094
Description
This PR handles loading
codegen.ts
in projects using ESM. Some of the approaches I tried:cosmiconfig
's configuration (nothing relevant that would make this work out of the box)ts-node
(I tried different configurations to be able to use await import)eval
:eval("import("pathname")"
I originally went with
execSync(tsc ...)
to compile the config file to CommonJS and cache the results. But the caching part has a bunch of edge cases so I took a different approach and usedjiti
to load the file.See benchmarks ⏳
ESM path — tsc, cache miss:
ESM path — tsc, cache hit:
ESM path — jiti:
.cts — jiti:
Non-ESM path:
Some of the next steps are:
graphql-config
as well (same issue) — PR: Support ESM and .mts/.cts extensions with jiti loader kamilkisiela/graphql-config#1286Related Closes #8509, Closes #8862, Closes #8809
Type of change
How Has This Been Tested?
Test Environment:
Checklist: