dotansimha / dotansimha/graphql-code-generator
client-preset babel-optimizer plugin does not remove unused imports
- 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.