apollographql / graphql-tag

A JavaScript template literal tag that parses GraphQL queries
MIT License
2.32k stars 175 forks source link

Build issues when using gql with ESM #804

Open aliok opened 11 months ago

aliok commented 11 months ago

When using ESM, gql becomes non-callable because TS doesn't like namespaces with ESM index.d.ts file:

export declare function gql(literals: string | readonly string[], ...args: any[]): DocumentNode;
export declare namespace gql {
    var _a: typeof import(".").gql;
    export { _a as default };
}

I get this error:

export const RepositorySummary = gql`
                                      ~~~
src/generated/queries.ts:6880:33 - error TS2349: This expression is not callable.

Similar to https://github.com/dotansimha/graphql-code-generator-community/issues/228

phryneas commented 11 months ago

Could you please create a TypeScript playground or reproduction project for that? This depends mostly on your personal setup, and I will not be able to replicate it with the information in your post alone.

kloostec commented 7 months ago

Here's an example: Playground Link

The error comes up as soon as you go into TS Config and change pretty much anything -- I set the Target to ES2022 for example and get the error immediately when the playground switched into ESM mode:

This expression is not callable. Type 'typeof import("file:///node_modules/graphql-tag/lib/index")' has no call signatures. (2349)

Josh-Cena commented 5 months ago

@phryneas This should help: https://arethetypeswrong.github.io/?p=graphql-tag%402.12.6

TimUnderhay commented 5 months ago

@phryneas I've had the same issue for some time. I've hacked my way around it through a "postcodegen" npm script, but fixing the library exports would be preferable.

sed -i \"s/import gql from 'graphql-tag'/import { gql } from 'graphql-tag'/\" src/gql/sdk.ts

StefanTheWiz commented 4 months ago

Building on @TimUnderhay's suggestion, I've noticed there's a hooks config option that appends the file name to the given command

import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  overwrite: true,
  schema: "...",
  documents: "...",
  generates: {
    "generated/types.ts": {
      plugins: [
        "typescript",
        "typescript-operations",
        //...
      ],
    },
  },
  hooks: {
    afterAllFileWrite: [
      `sed -i '' "s/import gql from 'graphql-tag'/import { gql } from 'graphql-tag'/"`
    ],
  },
};

export default config;