Is your feature request related to a problem? Please describe.
My ESLint config contains the @typescript-eslint/prefer-interface rule. The code generated by the TypeScript plugins outputs types across the board, which leads to ESLint errors鈥攂ut they are auto-fixable, so I only need to run eslint --fix and everything will be fine again!
Describe the solution you'd like
I'd love to be able to specify "lifecycle hooks" in the config that let me run commands once generation is finished over the generated files. As an added benefit, this would remove the need to build prettier support into the core library, as that could also simply be included in a lifecycle hook.
An example could be something like:
src/graphql.tsx:
plugins:
- "typescript"
- "typescript-operations"
hooks:
afterGenerate:
- prettier
- eslint --fix
There could also be lifecycle hooks for other lifecycles (before generate, after start, before end), but one that runs after the generation is the most interesting to me as it solves my immediate use case.
Describe alternatives you've considered
Hi @mxstbr !
I think generated files should get ignored by default, you can use add plugin to do so:
plugins:
- add: "/* eslint-disable */"
Regarding interface over type, please read my comment here regarding why we changed to types: https://github.com/dotansimha/graphql-code-generator/issues/1852#issuecomment-491692939
(TL;DR: type are easier to generate and maintain, and it's easier to detect generated conflicts and mismatches).
I really like your idea to allow executing scripts after generating. Today we are running prettier automatically per each file if it's installed in your project, but allow to developers to run other scripts makes a lot of sense.
I don't want to ignore them, as they are checked into source control and part of the codebase! They should adhere to the same standards as the rest of the codebase, whether that's formatting or linting rules.
The specific rule regarding types vs. interfaces was just the example I have right now, I don't have strong feelings towards or against interfaces. That could be any lint rule that I want to fix!
I don't want to ignore them, as they are checked into source control and part of the codebase!
The accepted wisdom is that generated code shouldn't be checked into source control, both because of the risk of generation sources and targets becoming out of sync, and because of the diff churn it creates.
The generated files are not really "part of the codebase" since you won't be editing them directly and any edits would be overwritten on the next generation.
Diff churn means that any changes to the sources would be amplified in the diffs, making code reviews more cumbersome, etc.
The one exception to this is when the generation is too slow to do on the fly, which doesn't apply to gql-gen, since it's not that slow even for larger projects.
That would mean failing CI (a ton of imported files are missing?!) and a more difficult initial development setup as the generation command has to be ran every time.
If that can be solved with e.g. a webpack loader #1828 (although what about types?) I am happy not to check those files in, or is there a different solution you are using for that?
That would mean failing CI ...
Same as the CI installs dependencies, it can also generate types, and the postinstall script allows automating this, including for other consumers of your package. A webpack loader would still require a build step for the types.
We actually prefer to use the codegen in CI and avoid committing the generated files, but that's just our preference. It also depends on how you load your schema (because if you load it from HTTP endpoint, it might not be available during CI build).
I appreciate the argument that generated files are not commonly committed and agree, but there are use cases where it is preferable to do so, and it would be great to have this suggested feature.
We have a set up between Ruby and TypeScript that makes sense to keep our generated files committed because there is some interdependency. Given that we treat the types as part of our code base, we'd rather it match our style than altogether disable eslint. Right now, we're having to write eslint --fix into the script with certain files, which, when paired with lint-staged triggers on other files, makes our automation process tricky and brittle with a lot of manually listing files in scripts.
If graphql-code-generator (which is 猸愶笍猸愶笍猸愶笍猸愶笍猸愶笍 by the way) could run our desired tool (eslint with plugins + prettier) instead of prettier alone, it would reduce our complexity.
@bbugh @mxstbr @slikts
I started the implementation here: https://github.com/dotansimha/graphql-code-generator/pull/2361
Added multiple types of hooks, and updated the dev-test examples to use that - everything seems to work.
One thing - the hooks: definition is implemented on the root level - which means that if you have multiple outputs with different hooks rules - you can't use it. Do you this this use-case is something we should take care of? Because it might take some more time, because currently the creation of the output and the write process (with the lifecycle hook) are separated, so we can't really bind between the output file and then fs write.
I think it's ready :)
Fixed all issues mentioned before and updated the docs. Now it's possible to specify hooks on output level as well.
Available as alpha 1.5.1-alpha-ffd58d6c.40.
You can now do:
hooks:
afterOneFileWrite:
- prettier --write
Available in 1.6.0, also replaces the prettify flag.
Most helpful comment
Same as the CI installs dependencies, it can also generate types, and the
postinstallscript allows automating this, including for other consumers of your package. A webpack loader would still require a build step for the types.