From 42eb137850294056b31dcd489228ce813e611030 Mon Sep 17 00:00:00 2001 From: jdecroock Date: Mon, 13 Mar 2023 11:39:58 +0100 Subject: [PATCH 01/12] remove defaultExchanges --- .changeset/calm-buckets-scream.md | 18 ++++++++++++++++++ packages/core/src/client.ts | 13 +++++-------- packages/core/src/exchanges/index.ts | 15 --------------- 3 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 .changeset/calm-buckets-scream.md diff --git a/.changeset/calm-buckets-scream.md b/.changeset/calm-buckets-scream.md new file mode 100644 index 0000000000..9a44434d4b --- /dev/null +++ b/.changeset/calm-buckets-scream.md @@ -0,0 +1,18 @@ +--- +'@urql/core': major +--- + +Remove `defaultExchanges` from `@urql/core` and make `exchanges` a required property on `Client` construction. +In doing so we make the `urql` package more tree-shakeable as the three default exchanges are in no code paths +meaning they can be removed if not used. + +A migration would look as follows if you are currently creating a client without exchanges + +```js +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/core' + +const client = createClient({ + url: '', + exchanges: [dedupExchange, cacheExchange, fetchExchange] +}); +``` diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 95e0ff376d..21a584e8a0 100755 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -23,7 +23,7 @@ import { import { DocumentNode } from 'graphql'; -import { composeExchanges, defaultExchanges } from './exchanges'; +import { composeExchanges } from './exchanges'; import { fallbackExchange } from './exchanges/fallback'; import { @@ -111,13 +111,13 @@ export interface ClientOptions { * This is the basis for how `urql` handles GraphQL operations, and exchanges handle the creation, execution, * and control flow of exchanges for the `Client`. * - * When this option is left out, the `Client` defaults to a list of {@link defaultExchanges}. By default, these - * will implement deduping, caching (via a document cache), and fetching (GraphQL over HTTP). + * To easily get started you should consider using the {@link dedupExchange}, {@link cacheExchange} and {@link fetchExchange} + * these are all exported from the core package. * * @see {@link https://formidable.com/open-source/urql/docs/architecture/#the-client-and-exchanges} for more information * on what `Exchange`s are and how they work. */ - exchanges?: Exchange[]; + exchanges: Exchange[]; /** A configuration flag indicating whether support for "Suspense" is activated. * * @remarks @@ -812,12 +812,9 @@ export const Client: new (opts: ClientOptions) => Client = function Client( dispatchDebug = next as ExchangeInput['dispatchDebug']; } - const exchanges = - opts.exchanges !== undefined ? opts.exchanges : defaultExchanges; - // All exchange are composed into a single one and are called using the constructed client // and the fallback exchange stream - const composedExchange = composeExchanges(exchanges); + const composedExchange = composeExchanges(opts.exchanges); // All exchanges receive inputs using which they can forward operations to the next exchange // and receive a stream of results in return, access the client, or dispatch debugging events diff --git a/packages/core/src/exchanges/index.ts b/packages/core/src/exchanges/index.ts index bfc2135080..3434aa7668 100644 --- a/packages/core/src/exchanges/index.ts +++ b/packages/core/src/exchanges/index.ts @@ -14,18 +14,3 @@ export type { export { mapExchange, mapExchange as errorExchange } from './map'; export type { MapExchangeOpts } from './map'; - -import { cacheExchange } from './cache'; -import { dedupExchange } from './dedup'; -import { fetchExchange } from './fetch'; - -/** The default list of exchanges a `Client` falls back to. - * - * @remarks - * When {@link ClientOptions.exchanges} isn’s passed, a {@link Client} is automatically - * created using this list of default exchanges. - * - * By default, this adds deduplication of operations, a basic document cache, - * and the built-in fetch exchange for GraphQL over HTTP. - */ -export const defaultExchanges = [dedupExchange, cacheExchange, fetchExchange]; From 8cb8a31a529340d9bef8b436ead237a62b8231ef Mon Sep 17 00:00:00 2001 From: jdecroock Date: Mon, 13 Mar 2023 11:44:55 +0100 Subject: [PATCH 02/12] update docs --- docs/advanced/authoring-exchanges.md | 1 - docs/advanced/subscriptions.md | 18 ++++++++++++------ docs/api/core.md | 11 +---------- docs/basics/core.md | 12 +++++------- docs/basics/react-preact.md | 8 ++++++-- docs/basics/svelte.md | 8 ++++++-- docs/basics/vue.md | 10 +++++++--- 7 files changed, 37 insertions(+), 31 deletions(-) diff --git a/docs/advanced/authoring-exchanges.md b/docs/advanced/authoring-exchanges.md index 41a342a9a6..2710f56bd7 100644 --- a/docs/advanced/authoring-exchanges.md +++ b/docs/advanced/authoring-exchanges.md @@ -283,7 +283,6 @@ The default order of exchanges is: ```js import { dedupExchange, cacheExchange, fetchExchange } from 'urql'; -// Also exported as `defaultExchanges`: [dedupExchange, cacheExchange, fetchExchange]; ``` diff --git a/docs/advanced/subscriptions.md b/docs/advanced/subscriptions.md index 96df7a5c4e..3a0e573c1d 100644 --- a/docs/advanced/subscriptions.md +++ b/docs/advanced/subscriptions.md @@ -13,12 +13,14 @@ APIs and ability to handle GraphQL subscriptions. To add support for subscriptions we need to add the `subscriptionExchange` to our `Client`. ```js -import { Client, defaultExchanges, subscriptionExchange } from 'urql'; +import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; const client = new Client({ url: 'http://localhost:3000/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription, }), @@ -45,7 +47,7 @@ object with a `.subscribe()` method accepting an observer. For backends supporting `graphql-ws`, we recommend using the [graphql-ws](https://github.com/enisdenjo/graphql-ws) client. ```js -import { createClient, defaultExchanges, subscriptionExchange } from 'urql'; +import { createClient, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; import { createClient as createWSClient } from 'graphql-ws'; const wsClient = createWSClient({ @@ -55,7 +57,9 @@ const wsClient = createWSClient({ const client = createClient({ url: '/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription: (operation) => ({ subscribe: (sink) => ({ @@ -84,7 +88,7 @@ package](https://github.com/apollographql/subscriptions-transport-ws) can be use > The `subscriptions-transport-ws` package isn't actively maintained. If your API supports the new protocol or you can swap the package out, consider using [`graphql-ws`](#setting-up-graphql-ws) instead. ```js -import { Client, defaultExchanges, subscriptionExchange } from 'urql'; +import { Client, dedupExchange, cacheExchange, fetchExchange, subscriptionExchange } from 'urql'; import { SubscriptionClient } from 'subscriptions-transport-ws'; const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { reconnect: true }); @@ -92,7 +96,9 @@ const subscriptionClient = new SubscriptionClient('ws://localhost/graphql', { re const client = new Client({ url: '/graphql', exchanges: [ - ...defaultExchanges, + dedupExchange, + cacheExchange, + fetchExchange, subscriptionExchange({ forwardSubscription: (operation) => subscriptionClient.request(operation) }), diff --git a/docs/api/core.md b/docs/api/core.md index b417e9b85d..7c9e5092c0 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -22,7 +22,7 @@ It accepts several options on creation. | Input | Type | Description | | ----------------- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `exchanges` | `Exchange[]` | An array of `Exchange`s that the client should use instead of the list of `defaultExchanges` | +| `exchanges` | `Exchange[]` | An array of `Exchange`s that the client should use | | `url` | `string` | The GraphQL API URL as used by `fetchExchange` | | `fetchOptions` | `RequestInit \| () => RequestInit` | Additional `fetchOptions` that `fetch` in `fetchExchange` should use to make a request | | `fetch` | `typeof fetch` | An alternative implementation of `fetch` that will be used by the `fetchExchange` instead of `window.fetch` | @@ -523,15 +523,6 @@ this problem. It's used by the [`Client`](#client) when the `maskTypename` option is enabled. -### defaultExchanges - -This is an array of the default `Exchange`s that the `Client` uses when the `exchanges` option isn't -passed. - -```js -const defaultExchanges = [dedupExchange, cacheExchange, fetchExchange]; -``` - ### composeExchanges This utility accepts an array of `Exchange`s and composes them into a single one. diff --git a/docs/basics/core.md b/docs/basics/core.md index 295aca9e5c..11742e5b61 100644 --- a/docs/basics/core.md +++ b/docs/basics/core.md @@ -134,10 +134,11 @@ The `@urql/core` package exports a function called `createClient` which we can u create the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from '@urql/core'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -153,6 +154,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -168,17 +170,13 @@ As we've seen above, the most important option for the `Client` is `url`, since without it. However, another important option on the `Client` is the `exchanges` option. This option passes a list of exchanges to the `Client`, which tell it how to execute our requests -and how to cache data in a certain order. By default, this will be populated with the list of -`defaultExchanges`. +and how to cache data in a certain order. ```js -import { createClient, defaultExchanges } from '@urql/core'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/core'; const client = createClient({ url: 'http://localhost:3000/graphql', - // the default: - exchanges: defaultExchanges, - // the same as: exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` diff --git a/docs/basics/react-preact.md b/docs/basics/react-preact.md index 3b20dc3483..269b519876 100644 --- a/docs/basics/react-preact.md +++ b/docs/basics/react-preact.md @@ -41,10 +41,11 @@ The `urql` and `@urql/preact` packages export a method called `createClient` whi create the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from 'urql'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -60,6 +61,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -76,10 +78,11 @@ To make use of the `Client` in React & Preact we will have to provide it via the the `Provider` export. ```jsx -import { createClient, Provider } from 'urql'; +import { createClient, Provider, dedupExchange, cacheExchange, fetchExchange } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); const App = () => ( @@ -245,6 +248,7 @@ import { createClient } from 'urql'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], // every operation will by default use cache-and-network rather // than cache-first now: requestPolicy: 'cache-and-network', diff --git a/docs/basics/svelte.md b/docs/basics/svelte.md index 0e884e6635..f2da40d149 100644 --- a/docs/basics/svelte.md +++ b/docs/basics/svelte.md @@ -48,10 +48,11 @@ The `@urql/svelte` package exports a method called `createClient` which we can u the GraphQL client. This central `Client` manages all of our GraphQL requests and results. ```js -import { createClient } from '@urql/svelte'; +import { createClient, dedupExchange, cacheExchange, fetchExchange } from '@urql/svelte'; const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], }); ``` @@ -67,6 +68,7 @@ GraphQL API. ```js const client = createClient({ url: 'http://localhost:3000/graphql', + exchanges: [dedupExchange, cacheExchange, fetchExchange], fetchOptions: () => { const token = getToken(); return { @@ -85,10 +87,11 @@ components. This will share one `Client` with the rest of our app, if we for ins ```html