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

Using codegen.ts in an ESM project causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error #225

Open
tars0x9752 opened this issue Oct 15, 2022 · 27 comments

Comments

@tars0x9752
Copy link

tars0x9752 commented Oct 15, 2022

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

  1. Add "type": "module" in package.json
  2. Run npx graphql-code-generator init and leave everything as default to create codegen.ts
  3. 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"]
}
@tars0x9752 tars0x9752 changed the title Using codegen.ts in a ESM projects causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error Using codegen.ts in an ESM projects causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error Oct 15, 2022
@tars0x9752 tars0x9752 changed the title Using codegen.ts in an ESM projects causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error Using codegen.ts in an ESM project causes cosmiconfig-typescript-loader to throw an "ES modules is not supported" error Oct 15, 2022
@Destreyf
Copy link

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 your codegen.ts file.
  • set module and moduleResolution to node16 in your tsconfig.ts
  • set type to module in package.json
  • modify generator command to use graphql-codegen-esm instead of graphql-codegen

A quick (empty) project seems to indicate this works on my end, but again I haven't tested with real project yet.

@tars0x9752
Copy link
Author

tars0x9752 commented Oct 16, 2022

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?

@Destreyf
Copy link

Destreyf commented Oct 16, 2022

@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.

@tars0x9752
Copy link
Author

tars0x9752 commented Oct 17, 2022

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".

@sirganya
Copy link

see this

@sirganya
Copy link

I'm also having the same issue.

@podefr
Copy link

podefr commented Oct 20, 2022

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 :)

@sirganya
Copy link

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.

@gterras
Copy link

gterras commented Oct 23, 2022

having the same issue I just switched my codegen to a yml format instead of ts so it doesn't use the TypeScriptLoader

Thanks a lot this solved my problem on a fresh sveltekit install
dotansimha/graphql-code-generator#8509

@sirganya
Copy link

Solved with this:

dotansimha/graphql-code-generator#8511 (comment)

@elijaholmos
Copy link

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.

@gterras
Copy link

gterras commented Nov 15, 2022

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.

It isn't supposed to defeat anything really, just the extension of your codegen config file.

@boehs
Copy link

boehs commented Nov 16, 2022

I need a JavaScript configuration for dotenv. Is there any workaround that allows JavaScript?

@Allaoua9
Copy link

Allaoua9 commented Dec 7, 2022

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"
}

@Allaoua9
Copy link

Allaoua9 commented Dec 7, 2022

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.

@boehs
Copy link

boehs commented Dec 25, 2022

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:

This is terrifying. Thank you

@mrchristophy
Copy link

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?

@khanakia
Copy link

khanakia commented Aug 19, 2023

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

@leonchabbey
Copy link

FYI I've created an issue that covers several issues with using typescript files (codegen and local plugins) with workarounds that might help.

@conayw
Copy link

conayw commented Oct 11, 2023

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
Copy link

Same issue in Next.js project (v14). Solved with this:

@zewas-digital
Copy link

@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...

@CatalinGheorghiu
Copy link

Same issue in Next.js project (v14). Solved with this:

This solved the issue

@develth
Copy link

develth commented Apr 9, 2024

Same issue in Next.js project (v14). Solved with this:

This solved the issue

Currently afterwards this pops:
const stripAnsi = require('strip-ansi');

So you also need a

yarn add -D strip-ansi

@aya-eiya
Copy link

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"
  }

@SPAHI4
Copy link

SPAHI4 commented Aug 10, 2024

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

@jay-l-e-e
Copy link

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

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

No branches or pull requests