graphql-code-generator-community
graphql-code-generator-community copied to clipboard
Using codegen.ts in an ESM project causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error
Describe the bug
I don't know if it's a bug or not, but I'm reporting it just in case. See steps to reproduce below for a more detailed bug/issue explanation.
In short, if you set "type": "module" in package.json and use codegen.ts as a config file, graphql-codegen fails because of ESM error by cosmiconfig-typescript-loader.
If you use codegen.yml or delete "type": "module" from package.json, the error will not occur.
Your Example Website or App
Not yet.
Steps to Reproduce the Bug or Issue
- Add
"type": "module"inpackage.json - Run
npx graphql-code-generator initand leave everything as default to createcodegen.ts - Run generated codegen npm script
graphql-codegen --config codegen.ts. It throws the following error:
TypeScriptLoader failed to compile TypeScript:
Must use import to load ES Module: /path/to/project/codegen.ts
require() of ES modules is not supported.
require() of /path/to/project/codegen.ts from /path/to/project/node_modules/cosmiconfig-typescript-loader/dist/cjs/index.js is an ES module file as it is a .ts file whose nearest parent package.json contains "type": "module" which defines all .ts files in that package scope as ES modules.
Instead change the requiring code to use import(), or remove "type": "module" from /path/to/project/package.json.
It maybe a bug in cosmiconfig-typescript-loader.
Expected behavior
Code generation completes without throwing an error.
Screenshots or Videos
No response
Platform
- OS: Linux x86_64
- NodeJS: 18.8.0
- "typescript": "4.8.4"
- "graphql": "16.6.0"
- "@graphql-codegen/cli": "2.13.7"
- "@graphql-codegen/typescript": "2.7.4"
- "@graphql-codegen/typescript-resolvers": "2.7.4"
Codegen Config File
No response
Additional context
a sample tsconfig.json
{
"compilerOptions": {
"outDir": "./dist",
"target": "es2021",
"lib": ["es2021"],
"module": "Node16",
"moduleResolution": "Node16",
"esModuleInterop": true
},
"include": ["src"]
}
Hey @tars0x9752,
I about to move a project of mine over to ESM and noticed that the generator has a specific section in the documentation on getting ESM working,
I'm sure you have already seen it, but just in case: https://the-guild.dev/graphql/codegen/docs/getting-started/esm-typescript-usage
I haven't started the ESM migration myself so it's possible additional steps outside of that documentation are needed.
The quick version is
- add
emitLegacyCommonJSImports: false,to yourcodegen.tsfile. - set
moduleandmoduleResolutiontonode16in yourtsconfig.ts - set
typetomodulein package.json - modify generator command to use
graphql-codegen-esminstead ofgraphql-codegen
A quick (empty) project seems to indicate this works on my end, but again I haven't tested with real project yet.
Thanks for the reply. As you've guessed, I've already seen that document. The thing is, even that document's exmaple doesn't use codegen.ts. They use codegen.yml in the example. And as far as I have tested, even if you follow that document it doesn't work with codegen.ts.
As I wrote in my first comment, if I use something other than codegen.ts, such as codegen.yml, then problem doesn't occur. So I'm not in that much trouble because I can use codegen.yml as a workaround.
A quick (empty) project seems to indicate this works on my end, but again I haven't tested with real project yet.
Does it work with codegen.ts?
@tars0x9752 I didn't look at the example project, just the documentation on that page.
I did notice that you're running the graphql-codegen executable in your initial post and not the graphql-codegen-esm executable.
What happens if you run the following:
npx graphql-codegen-esm --config codegen.ts
I'm not sure what package needs to be installed to use graphql-codegen-esm without the npx call as I haven't spent much time looking at it, npx (assuming you're using npm) will at at least run the command.
Thanks, but I've already tried graphql-codegen-esm too and that didn't work either.
It looks like cosmiconfig-typescript-loader cannot import codegen.ts if it's an ESM and requires the configuration file to be a CJS. (...probably they should consider using dynamic import instead of require.) FYI: https://github.com/Codex-/cosmiconfig-typescript-loader/blob/main/lib/loader.ts#L14
But these graphql libraries here such as graphql-config and @graphql-codegen/cli seem to be dependent on cosmiconfig-typescript-loader even if we use graphql-codegen-esm and codegen.ts with "type": "module".
I'm also having the same issue.
having the same issue I just switched my codegen to a yml format instead of ts so it doesn't use the TypeScriptLoader which uses require to load the codegen file. just a workaround for now, coming from the apollo docs it'd be great if they "just worked", but yml will do for now :)
I'm now having an error where @graphql-tools/code-file-loader is using require
Failed to load schema from ./src/gql/schema/*.ts: Failed to find any GraphQL type definitions in: ./src/gql/schema/*.ts; - Unable to load from file "/Users/sirganya/git/bwos/shared/src/gql/schema/getFiles.ts": Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/sirganya//git/bwos/shared/src/gql/s… require() of ES modules is not supported. require() of /Users/sirganya/git/bwos/shared/src/gql/schema/getFiles.ts from /Users/me/git/bwos/shared/node_modules/@graphql-tools/code-file-loader/cjs/load-from-module.js is an ES mod… Instead change the requiring code to use import(), or remove "type": "module" from /Users/sirganya/git/bwos/shared/package.json.
having the same issue I just switched my codegen to a
ymlformat instead oftsso it doesn't use theTypeScriptLoader
Thanks a lot this solved my problem on a fresh sveltekit install https://github.com/dotansimha/graphql-code-generator/issues/8509
Solved with this:
https://github.com/dotansimha/graphql-code-generator/issues/8511#issuecomment-1287214910
I'm having this problem as well, had to use a .yml config file to get around it. Annoying because that defats the purpose of using the TS config file in a TS project in the first place.
I'm having this problem as well, had to use a
.ymlconfig file to get around it. Annoying because that defats the purpose of using the TS config file in a TS project in the first place.
It isn't supposed to defeat anything really, just the extension of your codegen config file.
I need a JavaScript configuration for dotenv. Is there any workaround that allows JavaScript?
I guess that for now we have no other choice than using the yml config as this is an issue with cosmiconfig-typescript-loader see issue here.
You can follow the instructions here for generating ESM compliant code.
If you are generating code from an ESM typescript schema and you have an error of type ERR_UNKNOWN_FILE_EXTENSION you should be able to solve the issue by using ts-node/esm loader:
{
"codegen": "NODE_OPTIONS=\"--loader ts-node/esm\" graphql-codegen-esm --config codegen.yml"
}
As a workaround and in the case you absolutely want to use a codegen.ts config you can generate a yml config from the typescript config:
// codegen.ts
import yml from 'yaml';
import type {CodegenConfig} from '@graphql-codegen/cli';
import {writeFileSync} from 'fs';
const config: CodegenConfig = {
schema: 'src/graphql/schemas/schema.ts',
// ...
};
// save config as yml
writeFileSync('codegen.yml', yml.stringify(config));
export default config;
Then add the following script in your package.json :
{
// Generate codegen.yml then call graphql-codegen-esm
"codegen": "export NODE_OPTIONS=\"--loader ts-node/esm\" && node codegen.ts && graphql-codegen-esm --config codegen.yml"
}
This worked for me.
As a workaround and in the case you absolutely want to use a
codegen.tsconfig you can generate aymlconfig from the typescript config:
This is terrifying. Thank you
Hi, I'm having the same issue but none of the solutions are working for me. I've tried .ts, .yml, .cts config files and NODE_OPTIONS=\"--loader ts-node/esm\" If it makes a difference I'm trying to run it in a Nextjs project. No matter what I change I get the same error:
yarn run v1.22.19
$ graphql-codegen-esm --config codegen.cjs
/Users/me/Desktop/PROJECTS/project/node_modules/cli-truncate/index.js:3
const stringWidth = require('string-width');
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/me/Desktop/PROJECTS/project/node_modules/string-width/index.js from /Users/me/Desktop/PROJECTS/project/node_modules/cli-truncate/index.js not supported.
Instead change the require of /Users/me/Desktop/PROJECTS/project/node_modules/string-width/index.js in /Users/me/Desktop/PROJECTS/project/node_modules/cli-truncate/index.js to a dynamic import() which is available in all CommonJS modules.
at Object.<anonymous> (/Users/me/Desktop/PROJECTS/project/node_modules/cli-truncate/index.js:3:21) {
code: 'ERR_REQUIRE_ESM'
}
Any other ideas?
I was having the same error const stringWidth = require('string-width'); so i found out I had storybook installed which was using the string-width and conflicting with it so i removed all the storybook related packages and it worked
you can run this command to check
npm ls string-width
FYI I've created an issue that covers several issues with using typescript files (codegen and local plugins) with workarounds that might help.
I also encountered the same error.
$ yarn codegen
yarn run v1.22.19
$ graphql-codegen --config codegen.ts
/Users/xxx/xxx/project_nextjs/node_modules/cliui/build/index.cjs:291
const stringWidth = require('string-width');
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/xxx/xxx/project_nextjs/node_modules/string-width/index.js from /Users/xxx/xxx/project_nextjs/node_modules/cliui/build/index.cjs not supported.
Instead change the require of index.js in /Users/xxx/xxx/project_nextjs/node_modules/cliui/build/index.cjs to a dynamic import() which is available in all CommonJS modules.
It appears to be an unintentionally installed package due to a dependency.
I solved the problem by upgrading the yarn version. ( Current stable version was v1.3.2 )
$ yarn --version
1.22.19
$ yarn set version 1.3.2
$ yarn --version
1.3.2
@dimitriBouteille Was this the only thing you changed?
I am using these packages:
{ "name": "strapi-test", "version": "0.1.0", "private": true, "scripts": { "dev": "concurrently \"next dev\" \"yarn generate --watch\"", "build": "next build", "start": "next start", "lint": "next lint", "generate": "graphql-codegen" }, "dependencies": { "@apollo/client": "^3.9.0-rc.1", "@apollo/experimental-nextjs-app-support": "^0.8.0", "@graphql-codegen/cli": "^5.0.2", "@graphql-codegen/client-preset": "^4.2.2", "@types/dlv": "^1.1.4", "dlv": "^1.1.3", "graphql": "^16.8.1", "graphql-request": "^6.1.0", "next": "14.1.0", "react": "^18", "react-dom": "^18", "string-width": "4.2.3" }, "devDependencies": { "@graphql-codegen/cli": "^5.0.0", "@graphql-codegen/client-preset": "^4.1.0", "@parcel/watcher": "^2.3.0", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "autoprefixer": "^10.0.1", "concurrently": "^8.2.1", "eslint": "^8", "eslint-config-next": "14.1.0", "postcss": "^8", "tailwindcss": "^3.3.0", "ts-node": "^10.9.2" } }
I tried it with your command:
yarn add [email protected]
But i still get the same error...
Same issue in Next.js project (v14). Solved with this:
yarn add [email protected]
This solved the issue
Same issue in Next.js project (v14). Solved with this:
yarn add [email protected]This solved the issue
Currently afterwards this pops:
const stripAnsi = require('strip-ansi');
So you also need a
yarn add -D strip-ansi
Same issue in Next.js project (v14) & @graphql-codegen/cli v5.0.2.
Solved with this:
"resolutions": {
"cli-truncate": "^4.0.0",
"wrap-ansi": "^9.0.0",
"listr2": "^8.2.3",
"inquirer": "^10.1.0"
}
Same issue in Next.js project (v14) & @graphql-codegen/cli v5.0.2.
Solved with this:
"resolutions": { "cli-truncate": "^4.0.0", "wrap-ansi": "^9.0.0", "listr2": "^8.2.3", "inquirer": "^10.1.0" }
Codegen config loaded now, but client preset it can't find any documents
cross-env NODE_OPTIONS=--experimental-require-module graphql-codegen --config ./codegen.yaml
Solved with this. This feature enabled by default at the NodeJS 22.12.0 See: This PR