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

Some enhancements for hooks #1347

Closed
wants to merge 5 commits into from
Closed

Some enhancements for hooks #1347

wants to merge 5 commits into from

Conversation

ardatan
Copy link
Collaborator

@ardatan ardatan commented Feb 24, 2019

  • Remove withSubscriptionHooks
  • Use the same behaviour that @FredyC added in here but in a different way, I think we can uae same withHooks option to provide custom module for hooks.
  • Fix missing ReactApollo import if noComponents is true, but noHOC is false.
  • Change noComponents and noHOC to withComponents and withHOC which look more consistent with withHooks.
  • Fixed invalid import syntax
  • gqlImport is more consistent with other import syntaxes in codegen. gqlImport: graphql.macro#gql

@ardatan ardatan changed the title Some enhancements for hooks WIP:vSome enhancements for hooks Feb 24, 2019
@ardatan ardatan changed the title WIP:vSome enhancements for hooks WIP: Some enhancements for hooks Feb 24, 2019
Signed-off-by: Arda TANRIKULU <ardatanrikulu@gmail.com>
@ardatan ardatan requested a review from dotansimha February 24, 2019 11:04
@ardatan ardatan changed the title WIP: Some enhancements for hooks Some enhancements for hooks Feb 24, 2019
Signed-off-by: Arda TANRIKULU <ardatanrikulu@gmail.com>
@@ -52,13 +52,13 @@ Or if you prefer:
Customize from where will be `gql` imported. This is useful if you want to use eg. `graphql.macro` for inlining documents.
Note that you need to write whole import line, eg. `import { gql } from 'graphql.macro'`.

#### `noHOC` (default value: `false`)
#### `withHOC` (default value: `true`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like unnecessary breaking change just for switching logic around. If anything, it should still support old flags, just deprecate them and convert into these.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @FredyC . I think it's better to change it back @ardatan :)

#### `withSubscriptionHooks` (default value: `false`)

This will cause the codegen to add React **Hooks** even for _Subscriptions_.
You can specify alternative module that is exports `useQuery` `useMutation` and `useSubscription`. This is useful for further abstraction of some common tasks (eg. error handling). Filepath relative to generated file can be also specified. But if you provide only `true`, it will use `react-apollo-hooks` by default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't feel right to abuse the boolean flag to also have a string value. I would keep it separate, nothing wrong about.

const config = options.data.root.config || {};
return operationType !== 'subscription' || config.withSubscriptionHooks;
return config.gqlImport || "import gql from 'graphql-tag'";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not include this in the getImports as well?

): Promise<string> => {
config.withHOC = 'withHOC' in config ? config.withHOC : true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a personal preference, probably not a big different

Suggested change
config.withHOC = 'withHOC' in config ? config.withHOC : true;
config.withHOC = config.withHOC !== undefined ? config.withHOC : true;

{{#if @root.config.withHooks}}
import * as ReactApolloHooks from 'react-apollo-hooks';
{{/if}}
{{{getImports}}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got burned by this as well :)

Suggested change
{{{getImports}}}
{{{getImports this}}}

@ardatan ardatan changed the title Some enhancements for hooks WIP: Some enhancements for hooks Feb 24, 2019
@ardatan
Copy link
Collaborator Author

ardatan commented Feb 24, 2019

I also think there is another inconsistency between gqlImport and importHooks; because while importHooks takes the name of the module, gqlImport takes all the import expression.

@danielkcz
Copy link
Contributor

Yea well, if you have a better idea... I've explained in #1344

@danielkcz
Copy link
Contributor

Btw, that's also why there is a different name gqlImport for a full import an hooksImportFrom to clearly denote a difference. That's also why the withHooks should not be used for supplying the module name. It's confusing when someone looks at it without diving into docs.

@ardatan
Copy link
Collaborator Author

ardatan commented Feb 24, 2019

We use typeModule#ContextType syntax in mappers, so I think this can be used here. The other thing we should consider noGraphqlTag option as well. If this is set to true with gqlImport, TS compiler can give some errors if you set noUnusedImports in your tsconfig.json.
After my change in this PR, if you set gqlImport to false, codegen will render gql tags without any putting gql tags before document strings. I think using two different configuration fields can make inconsistency. If we use two different options there; the code can get messy.
I think same for withHooks and importHooks stuff; because I think we should keep number of config fields as less as possible.

@ardatan ardatan changed the title WIP: Some enhancements for hooks Some enhancements for hooks Feb 24, 2019
@danielkcz
Copy link
Contributor

Ok, it's an interesting approach, I suppose it will work, but it requires a better documentation as it's not the usual approach :)

The other thing we should consider noGraphqlTag option as well. If this is set to true with gqlImport

Yea, this config option is not even documented, so I doubt someone was using it :) What do you think @dotansimha?

After my change in this PR, if you set gqlImport to false, codegen will render gql tags without any putting gql tags before document strings.

I guess it makes sense, not sure who would actually use that, but 🙈

I think same for withHooks and importHooks stuff; because I think we should keep number of config fields as less as possible.

I don't think it makes a difference to have one or two extra configs. It's a DEV tool after all. It's more about clarity so it's apparent from the first view what each config does. You shouldn't be forced look into docs every time you need to tweak something.

@leonardfactory
Copy link
Contributor

I'd cast a vote for different options (like I originally implemented them). More options, with clean docs, allows us to output clear errors if plugin is configured badly. I may understand something like we accepts a list of foos or just a single foo, but switching boolean with string seems not so useful in this case. However, enough bikeshedding for today! 🎉

DAB0mB pushed a commit that referenced this pull request Feb 26, 2019
- Add gqlImport config option
- Remove `withSubscriptionHooks`
- Fix missing `ReactApollo` import if `noComponents` is true, but `noHOC` is false.
- Fixed invalid import syntax
- `gqlImport` is more consistent with other import syntaxes in codegen. `gqlImport: graphql.macro#gql`
DAB0mB pushed a commit that referenced this pull request Feb 26, 2019
- Add gqlImport config option
- Remove `withSubscriptionHooks`
- Fix missing `ReactApollo` import if `noComponents` is true, but `noHOC` is false.
- Fixed invalid import syntax
- `gqlImport` is more consistent with other import syntaxes in codegen. `gqlImport: graphql.macro#gql`
@ardatan ardatan closed this Feb 26, 2019
@ardatan ardatan deleted the enhancements-hooks branch February 26, 2019 16:31
@sandiiarov
Copy link

sandiiarov commented Mar 2, 2019

We use typeModule#ContextType syntax in mappers, so I think this can be used here. The other thing we should consider noGraphqlTag option as well. If this is set to true with gqlImport, TS compiler can give some errors if you set noUnusedImports in your tsconfig.json.
After my change in this PR, if you set gqlImport to false, codegen will render gql tags without any putting gql tags before document strings. I think using two different configuration fields can make inconsistency. If we use two different options there; the code can get messy.
I think same for withHooks and importHooks stuff; because I think we should keep number of config fields as less as possible.

@ardatan @FredyC But, what if I want to use gql from graphql-tag.macro?
When I use gqlImport: graphql-tag.macro the generated file has import gql from "graphql-tag.macro"; and also has parsed GraphQL queries.

Example with gqlImport: graphql-tag.macro
This is generated file 👇

import gql from "graphql-tag.macro";
import * as ReactApolloHooks from "react-apollo-hooks";

// ====================================================
// Fragments
// ====================================================

export const WitnessInfoFragmentDoc = {
  kind: "Document",
  definitions: [
    {
      kind: "FragmentDefinition",
      name: { kind: "Name", value: "WitnessInfo" },
      typeCondition: {
        kind: "NamedType",
        name: { kind: "Name", value: "Witness" }
      },
      directives: [],
      selectionSet: {
        kind: "SelectionSet",
        selections: [
          {
            kind: "Field",
            name: { kind: "Name", value: "id" },
            arguments: [],
            directives: []
          },
          {
            kind: "Field",
            name: { kind: "Name", value: "firstName" },
            arguments: [],
            directives: []
          },
          {
            kind: "Field",
            name: { kind: "Name", value: "lastName" },
            arguments: [],
            directives: []
          },
          {
            kind: "Field",
            name: { kind: "Name", value: "croppedImage" },
            arguments: [],
            directives: []
          }
        ]
      }
    }
  ],
  loc: { start: 0, end: 103 }
};

How can I stop parsing the GraphQL queries and use graphql-tag.macro with this PR?

I am trying to understand the logic of this 23894f0#diff-518180923419f5ff9c24c6d9b7d61651R86

return config.gqlImport ? JSON.stringify(gqlTag(doc)) : 'gql`' + doc + '`';

If gqlImport is not false, undefined, etc -> transform gql to AST? But this is exactly an opposite that config tells, isn't?

Probably you should consider showing a warning message if noGraphqlTag is set to true with gqlImport instead of changing that code.

@danielkcz
Copy link
Contributor

@sandiiarov Do you realize that's what is the macro about? To inline parsed document so it doesn't need to be done on runtime :)

@sandiiarov
Copy link

@FredyC Yes, I do. Do you understand what I am trying to ask? Do you understand how JSON.stringify(gqlTag(doc)) is working?

@sandiiarov
Copy link

sandiiarov commented Mar 2, 2019

When I use gqlImport: graphql-tag.macro I want to get

import gql from "graphql-tag.macro";

export const WitnessInfoFragmentDoc = gql`
  fragment WitnessInfo on Witness {
    id
    firstName
    lastName
  }
`;

but getting this

import gql from "graphql-tag.macro";

export const WitnessInfoFragmentDoc = {
  kind: "Document",
  definitions: [
    {
      kind: "FragmentDefinition",
      name: { kind: "Name", value: "WitnessInfo" },
      typeCondition: {
        kind: "NamedType",
        name: { kind: "Name", value: "Witness" }
      },
      directives: [],
      selectionSet: {
        kind: "SelectionSet",
        selections: [
          {
            kind: "Field",
            name: { kind: "Name", value: "id" },
            arguments: [],
            directives: []
          },
          {
            kind: "Field",
            name: { kind: "Name", value: "firstName" },
            arguments: [],
            directives: []
          },
          {
            kind: "Field",
            name: { kind: "Name", value: "lastName" },
            arguments: [],
            directives: []
          }
        ]
      }
    }
  ],
  loc: { start: 0, end: 88 }
};

@FredyC Does it make sense to you?

@danielkcz
Copy link
Contributor

Ah, I see what you mean now. Looks like that @DAB0mB introduced that mistake when merging some of @ardatan changes in 859de36. Originally there was different option (which wasn't really documented).

config.noGraphqlTag ? JSON.stringify(gqlTag(doc)) : 'gql`' + doc + '`';

The logic should be reversed with gqlImport option.

@dotansimha
Copy link
Owner

@FredyC you are right, we fixed it in the refactor :)

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

Successfully merging this pull request may close these issues.

5 participants