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

Schema config param is not fully compatible with GQLCodeGen; Improper caching of complex schemas #649

Open
comp615 opened this issue Mar 21, 2023 · 1 comment

Comments

@comp615
Copy link
Contributor

comp615 commented Mar 21, 2023

GQLCodeGen supports several formats for the schema files used to do codegen. This include formats like remote URLs or TS/JS files that generate the schema.

The way Graphql-Let works today, its config is more or less directly passed through to the underlying GQLCodeGen CLI. This means that if you set your config to something like a remote file or TS file, the schema will actually be correctly generated.

The problem arises when you change that schema and re-run codegen. Before the config is passed through to the underlying CLI, graphql-let does some hashing / processing on it to determine if it should be run. The issue is that specific processing only handles literal files. If you browse the code, you can see there's a TODO and it filters out URLs. For TS/JS files...it can be very misleading because it will work, but it will actually hash the file itself (not the result of running the file which actually makes the schema)

This both:

  • Leads to situations where caching is improperly handled and does not appear to regenerate
  • Decreases overall API compatibility with CodeGen
@comp615
Copy link
Contributor Author

comp615 commented Apr 19, 2023

A few thoughts on potential approaches here:

One naiive way would be to simply extend the existing code to handle exported modules (i.e. just like we kind of have a URL loader and a simple file loader today, we could add one more). The downside of this is that it's still not API compatible and we are ultimately maintaining a copy of the same code

The most compatible way would be to use the underlying GQL Tools loaders as shown in #650. However, this approach has a few drawbacks. First and foremost...it's slow. While it's acceptably slow for the batch use case, the webpack loader case is slow to the point of making this non-viable. In a project with dozens of GQL files, each file is treated independently by the loader; meaning each builds a separate execContext which reads the schema. This now goes from 1ms to 200ms or more, bringing builds to a crawl. Some of this might be caused by GQL Tools kicking back a Schema object instead of raw file we can hash.

One solution to that problem is to cache the execContext or schema in the loader (since it is a singleton). But now we have the reverse problem, we never reevaluate the schema. So hot reloading is useless. In effect, loaders do not know when the entire build is done, nor do we get a list of files involved in building the schemas such that we could watch them in the loader.

So to actually solve this problem, it's very likely that we should convert the loader to a plugin with a loader component. These two would be able to better coordinate since we could produce a cached schema per build that could be reused for each file. Then on subsequent builds (i.e. hot reloads) we could simply re-create the schema.

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

1 participant