Graphql-code-generator: Allow running prettier/formatting before writing to disk

Created on 10 Oct 2019  路  8Comments  路  Source: dotansimha/graphql-code-generator

Is your feature request related to a problem? Please describe.

After https://github.com/dotansimha/graphql-code-generator/releases/tag/v1.6.0, we've used a hook with afterAllFileWrite: prettier --write. The problem is that since this applies after files have been written to disk, all watchers are triggered even if the content is identical, then when that run is complete (riddled with lint errors that take a long time for webpack to render), the watcher is triggered again since the files have been formatted.

Describe the solution you'd like
A hook that runs before files are written to disk that allows us to format the content using the tool of our choice (e.g. prettier or eslint).

Describe alternatives you've considered
N/A

Additional context

N/A

core enhancement

Most helpful comment

Maybe by having some sort of postprocess hook that's a module.

export function postprocess(content: string, filename: string): string;

So right before you write to disk, you pass it through this module that can manipulate content however it wants and returns a modified (or not) content that you then write to disk

All 8 comments

@SimenB sounds like a good idea, but how can we pass the content to prettier without writing it to the disk?

Maybe by having some sort of postprocess hook that's a module.

export function postprocess(content: string, filename: string): string;

So right before you write to disk, you pass it through this module that can manipulate content however it wants and returns a modified (or not) content that you then write to disk

I tried looking into this now, and lifecycle hooks are a really bad fit - they want to spawn a binary and ignore anything it might want to return, and doesn't support running an arbitrary node script and passing it arguments. I'd have to add some executable to $PATH to achieve what I want, which is pretty bad DX I think. What I essentially want is to be able to format the string you hold in memory, so the currentHash === previousHash check passes and no file is written to disk.

https://github.com/dotansimha/graphql-code-generator/blob/38a0cb15482bef36641038564af09fa39ea37fce/packages/graphql-codegen-cli/src/generate-and-save.ts#L38-L50

I don't want to spend a bunch of time adding a completely new API without some input from the maintainers. My original idea was to just add a hook, but as mentioned, I don't think that fits the other hooks _at all_. But maybe we could add a new config called moduleHooks or something, which are required and executed?

Here's an approach I've seen: https://github.com/ForbesLindesay/typescript-json-validator/blob/9538f99ea75967a7a6caf776bd3d1db986b21f1b/src/prettierFile.ts

If prettier is installed, it runs it. If not, it's a no-op. It doesn't do it in memory, but I'm not actually sure if that is a disadvantage.

I need it to run in memory to avoid the FS operation that triggers watchers. Or at least _two_ FS operations triggering any watchers twice. What you've linked can be achieved currently via the afterOneFileWrite or afterAllFileWrite hooks

I could be misunderstanding your issue, but couldn't you add all your generated files to a .prettierignore file?

I want the output to look pretty, though

If the config file is a JS file or the API is used it would be great if we could just supply a function taking a string and returning a string (or Promise of a string) which we could easily pass prettier.format() to

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jagregory picture jagregory  路  3Comments

iamdanthedev picture iamdanthedev  路  3Comments

edorivai picture edorivai  路  3Comments

SimenB picture SimenB  路  3Comments

quolpr picture quolpr  路  3Comments