Skip to content

Commit

Permalink
Add experimental codegen support to CLI (#707)
Browse files Browse the repository at this point in the history
* Infer return and variable types from query string argument

* Make arguments optional if variables are not required

* Force optional arguments when not using codegen

* Ignore country and language when checking optional arguments

* New @shopify/hydrogen-codegen package

* Add vendor patch for graphql-tag-pluck

* Remove unused deps and add comments

* Add codegen to hello-world template

* Remove codegen from generated JS templates

* Use Pick instead of primitives for generated operations

* Remove unnecessary properties in package.json

* Add comments and rename some generics

* Simplify storefront types for codegen

* Add createRequire in ESM build

* Fix typecheck

* Disable tests for now

* Prettier readme

* Use any by default for the return type

* Adjust new lines and exports

* Check custom plugins and export hydrogen plugin

* wip

* Update visitor implementation

* Make fragment and query names unique in demo-store

* Change namespace and import path

* Better separate plugin from preset

* Log error

* Fix generated code order

* Separate preset from utilities

* Reorganize files

* Fix ESM build

* Use JSON schema from Hydrogen package

* Specify extensions in imports and fix CJS build

* Change graphql-tag-pluck patching strategy

* Add experimental-codegen command

* Add codegen to dev command with a flag

* Fix config path flag in dev command

* Generate Oclif manifest

* Remove files from templates

* Fix pluck paths during tests

* Add unit tests

* Fix deps

* Fix clean-all, update package-lock

* Wrap require.resolve in try-catch

* Make schema accessible without building Hydrogen first

* Patch pluck before importing codegen cli

* Cleanup

* Improve error messages

* Feedback update

* Fix tests

* Update package.json and make package publishable

* Update flag descriptions

* Changesets and docs

* Change default generated file name

* Fix paths on Windows
  • Loading branch information
frandiox authored May 17, 2023
1 parent cd72b4a commit 112ac42
Show file tree
Hide file tree
Showing 31 changed files with 2,449 additions and 676 deletions.
70 changes: 70 additions & 0 deletions .changeset/friendly-clouds-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
'@shopify/cli-hydrogen': minor
---

Add **UNSTABLE** support for GraphQL Codegen to automatically generate types for every Storefront API query in the project via `@shopify/hydrogen-codegen`.

> Note: This feature is unstable and subject to change in patch releases.
How to use it while unstable:

1. Write your queries/mutations in `.ts` or `.tsx` files and use the `#graphql` comment inside the strings. It's important that every query/mutation/fragment in your project has a **unique name**:

```ts
const UNIQUE_NAME_SHOP_QUERY = `#graphql
query unique_name_shop { shop { id } }
`;
```

If you use string interpolation in your query variables (e.g. for reusing fragments) you will need to specify `as const` after each interpolated template literal. This helps TypeScript infer the types properly instead of getting a generic `string` type:

```ts
const UNIQUE_NAME_SHOP_FRAGMENT = `#graphql
fragment unique_name_shop_fields on Shop { id name }
`;

const UNIQUE_NAME_SHOP_QUERY = `#graphql
query unique_name_shop { shop { ...unique_name_shop_fields } }
${UNIQUE_NAME_SHOP_FRAGMENT}
` as const;
```

2. Pass the queries to the Storefront client and do not specify a generic type value:

```diff
-import type {Shop} from '@shopify/hydrogen/storefront-api-types';
// ...
-const result = await storefront.query<{shop: Shop}>(UNIQUE_NAME_SHOP_QUERY);
+const result = await storefront.query(UNIQUE_NAME_SHOP_QUERY);
```

3. Pass the flag `--codegen-unstable` when running the development server, or use the new `codegen-unstable` command to run it standalone without a dev-server:

```bash
npx shopify hydrogen dev --codegen-unstable # Dev server + codegen watcher
npx shopify hydrogen codegen-unstable # One-off codegen
npx shopify hydrogen codegen-unstable --watch # Standalone codegen watcher
```

As a result, a new `storefrontapi.generated.d.ts` file should be generated at your project root. You don't need to reference this file from anywhere for it to work, but you should commit it every time the types change.

This comment has been minimized.

Copy link
@juanpprieto

juanpprieto May 19, 2023

Contributor

@frandiox Do we really need to commit this file?

This comment has been minimized.

Copy link
@frandiox

frandiox May 22, 2023

Author Contributor

Not committing this file means that a project needs to run commands before it finds types, which can bring issues on CI / typecheck.
Also, this file exports types that can be used in function parameters so I think the file should always be there:

import type {ShopLayoutQuery} from '~/storefrontapi.generated';

function doSomething(data: ShopLayoutQuery) { ... }

export async function loader({context: {storefront}}) {
  const result = await storefront.query(`#graphql\n query shop_layout {...}`);

  doSomething(result);

  return ...;
}

It's just like if we were generating a JS wrapper around queries 🤔


**Optional**: you can tune the codegen configuration by providing a `<root>/codegen.ts` file (or specify a different path with the `--codegen-config-path` flag) with the following content:

```ts
import type {CodegenConfig} from '@graphql-codegen/cli';
import {preset, pluckConfig, schema} from '@shopify/hydrogen-codegen';

export default <CodegenConfig>{
overwrite: true,
pluckConfig,
generates: {
['storefrontapi.generated.d.ts']: {
preset,
schema,
documents: ['*.{ts,tsx}', 'app/**/*.{ts,tsx}'],
},
},
};
```

Feel free to add your custom schemas and generation config here or read from different document files. Please, report any issue you find in our repository.
7 changes: 7 additions & 0 deletions .changeset/hot-cats-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@shopify/hydrogen-codegen': patch
---

New package that provides GraphQL Codegen plugins and configuration to generate types automatically for Storefront queries in Hydrogen.

While in alpha/beta, this package should not be used standalone without the Hydrogen CLI.
5 changes: 5 additions & 0 deletions .changeset/selfish-zebras-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/hydrogen': patch
---

Add support for generated types from the new unstable codegen feature in the CLI.
Loading

0 comments on commit 112ac42

Please sign in to comment.