graphql-code-generator icon indicating copy to clipboard operation
graphql-code-generator copied to clipboard

Local ESM typescript plugin fails to load when using ts-node/esm

Open leonchabbey opened this issue 2 years ago • 1 comments

Which packages are impacted by your issue?

@graphql-codegen/cli

Describe the bug

When trying to use a local ESM typescript plugin, the plugin fails to load. The issue happens because ts-node/esm reports error differently than node and causes an edge case on a condition during load.

There is actually two issues affecting the use of ESM typescript plugin:

1) Relative path resolving doesn't work in ESM mode

This seems to be already known.

As a workaround for now, the plugin's path needs to be absolute:

import path from 'path';

import { Types } from '@graphql-codegen/plugin-helpers';

const config: Types.Config = {
  schema: 'http://localhost:3000/graphql',
  emitLegacyCommonJSImports: false,
  generates: {
    'src/types/generated.ts': {
      plugins: [
        path.resolve(__dirname, './my-plugin.ts') // <----
      ],
      config: {
        ...
      },
    },
  },
};

export default config;

2) Module loading always crashes because of incompatible condition based on error's code

Inside the file plugin.ts, it crashes when the module cannot be loaded based on the error's code. However, ts-node doesn't report a code when crashing which makes this condition always true and it never gets to the point of trying to load the plugin with its full path.

The following quick patch fixes the issue: https://gist.github.com/leonchabbey/cbabda67f94d13a28697a7381927b18c

Your Example Website or App

Steps to Reproduce the Bug or Issue

Expected behavior

To not have to apply a patch and to be able to use relative path.

For now, here is a full working setup:

// package.json (force loader to be ts-node/esm)

{
  "scripts": {
    "codegen": "VERBOSE=1 NODE_OPTIONS=\"--loader ts-node/esm\" graphql-codegen-esm --config codegen.ts",
}

// codegen.ts (reference your plugin with an absolute path)
  
import path from 'path';
import { Types } from '@graphql-codegen/plugin-helpers';

const config: Types.Config = {
  ...,
  generates: {
    'src/types/generated.ts': {
      plugins: [
        path.resolve(__dirname, './my-plugin.ts')
      ],
      ...,
    },
  },
};

export default config;

// @graphql-codegen/cli (apply patch)
https://gist.github.com/leonchabbey/cbabda67f94d13a28697a7381927b18c

Screenshots or Videos

No response

Platform

  • OS: macOS
  • NodeJS: 16
  • graphql version: 15
  • @graphql-codegen/* version(s): 5.0.0

Codegen Config File

No response

Additional context

No response

leonchabbey avatar Aug 22 '23 10:08 leonchabbey

For someone who is experincing the same issue: Using tsx instead of ts-node would mitigate this issue.

  • NODE_OPTIONS='--import tsx' graphql-codegen-esm // for node 20 and higher
  • NODE_OPTIONS='--loader tsx' graphql-codegen-esm // for node 18

HelloWorld017 avatar Jun 26 '24 05:06 HelloWorld017