dotansimha / dotansimha/graphql-code-generator

client-preset babel-optimizer plugin does not remove unused imports

Open
#9,661 0 comments 1 reaction 0 assignees View on GitHub
Dominant language
TypeScript
Stars
11.3k
Forks
1.4k
Avg merge
1d 1h
Merged PRs (30d)
23

Description

### Which packages are impacted by your issue?

@graphql-codegen/client-preset

### Describe the bug

The client-preset's [babel optimizer plugin](https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#babel-plugin) removes inline GraphQL query strings, and replaces them with references to the compiled form of those queries contained within the preset's generated output.

For example:
```ts
import { graphql } from '~/generated`';

console.log(graphql(`
query MyQuery {
someField
}
`);
```

would be compiled into something like:

```ts
import { graphql } from '~/generated`'; // UNUSED
import { MyQueryDocument } from '~/generated/graphql';

console.log(MyQueryDocument);
```

If you're using a modern bundler such as Rollup (and probably recent versions of Webpack), those tools will tree-shake unused imports, and will simply inline `MyQueryDocument` into the above script, producing output that looks something like:

```ts
const MyQueryDocument = { blah: 'blah blah' };
console.log(MyQueryDocument);
```

**However**, if you are not using a bundler (or are using a bundler that is less-aggressive about tree-shaking such as [Metro](https://github.com/facebook/metro/)), that `import { graphql } from '~/generated`';` will remain in the compiled output.

This output will (pointlessly) include the entirety of `generated/gql.ts`, which contains an extra copy of every GraphQL query string, looking something like:

```ts
const documents = {
"\n query MyQuery {\n someField\n }\n": types.MyQueryDocument
};
```

In other words, the Babel plugin currently leaves behind unused imports that will cause a fairly large, useless file to be included with our application.

In this case, the output is quite large, so I won't post it inline here, but you can see an example at the link below.

### Your Example Website or App

https://stackblitz.com/edit/github-yn4wny-xroulz?file=output-metro%2Fbundle.js

### Steps to Reproduce the Bug or Issue

In the above stackblitz project, I've included:

* A sample application in `/app`
* The codegen output in `/app/graphql`
* The compiled output of the Babel plugin in `/lib`
* rollup's output (run against `lib`) in `/output-rollup`, which _has_ been tree-shaken to remove references to dead code
* metro (react-native)'s output in `/output-metro`, which contains quite a bit of dead code that the Babel plugin left behind

### Expected behavior

I believe that it would be desirable for the Babel optimizer plugin to strip out any imports of the `graphql` helper function (which should become unused after the plugin substitutes inline queries with references)

Furthermore, it may be desirable for the plugin to behave differently when using a `documentMode` such as `string` or `graphqlTag`. In those cases, a smaller and more-efficient bundle could be achieved by simply replacing the `graphql` function-call with an inline string, or a reference to `graphql-tag` (or similar).

### Screenshots or Videos

_No response_

### Platform

N/A

### Codegen Config File

_No response_

### Additional context

_No response_

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.