Mirror: The small sibling of the graphql package, slimmed down for client-side libraries.
1<div align="center">
2 <h2 align="center">graphql-web-lite</h2>
3 <p align="center"><strong>The small sibling of the <code>graphql</code> package, slimmed down for client-side libraries</strong></p>
4 <br />
5 <a href="https://npmjs.com/package/graphql-web-lite">
6 <img alt="NPM Version" src="https://img.shields.io/npm/v/graphql-web-lite.svg" />
7 </a>
8 <a href="https://npmjs.com/package/use-interactions">
9 <img alt="License" src="https://img.shields.io/npm/l/graphql-web-lite.svg" />
10 </a>
11 <a href="https://bundlephobia.com/result?p=graphql-web-lite">
12 <img alt="Minified gzip size" src="https://img.shields.io/bundlephobia/minzip/graphql-web-lite.svg?label=gzip%20size" />
13 </a>
14 <br />
15 <br />
16</div>
17
18The `graphql` package serves two purposes in being the reference implementation of the
19[GraphQL specification](https://spec.graphql.org/) and being used as the shared toolkit
20for implementing GraphQL in client-side and server-side JavaScript applications. This
21can cause bloat for client-side apps, where we'd rather choose lower bundlesize impact
22over fidelity.
23
24`graphql-web-lite` provides an alias package that can be swapped in for the standard
25`graphql` package in client-side applications.
26It aims to reduce the size of imports that are in common use by GraphQL clients and
27users, while still providing most `graphql` exports that are used in other contexts.
28
29It replaces the default `language` exports with
30[`@0no-co/graphql.web`](https://github.com/0no-co/graphql.web) for a leaner
31parser, printer, and visitor, which only support the GraphQL query language and
32are tested to 100% coverage and built to match GraphQL.js’ performance.
33
34In an average app using the GraphQL library for a GraphQL client aliasing this
35package could save you 7kB gzip effortlessly.
36
37> **Note:** If you’re using `@urql/core@^4` you’re already benefitting from
38> `@0no-co/graphql.web`’s size reduction and aliasing `graphql-web-lite` will
39> only benefit you if you import from `graphql` in any of your other code or
40> libraries.
41
42## Installation
43
44`graphql-web-lite` mirrors the folder structure of the regular `graphql` package and
45includes mostly the same files and imports as the `graphql` package, minus a couple
46that aren't commonly used for client-side GraphQL.
47This offers us several installation options, depending on how the package is aliased
48to the regular `"graphql"` import.
49
50<details>
51<summary><strong>Installation with <code>package.json</code> aliases</strong></summary>
52
53When your dependencies and `node_modules` folder isn't used by a _GraphQL server_ and
54only used by a _GraphQL clients_, you can use a quick and easy npm installation alias.
55In your `package.json` file you can define your `graphql` installation to use
56`graphql-web-lite` instead, which is supported by both Yarn and npm:
57
58```diff
59{
60 "dependencies": {
61- "graphql": "^16.6.0"
62+ "graphql": "npm:graphql-web-lite@^16.6.0-3"
63 }
64}
65```
66
67Alternatively, you can run an installation command to alias the package:<br />
68
69```sh
70npm install --save graphql@npm:graphql-web-lite
71# or
72yarn add graphql@npm:graphql-web-lite
73```
74
75When this isn't suitable — for instance, because the same dependencies are shared
76with an API or server-side GraphQL consumer, or you're working inside a monorepo —
77you can try one of the other aliasing techniques below.
78
79</details>
80
81<details>
82<summary><strong>Installation with Webpack aliases</strong></summary>
83
84First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
85package.
86
87```sh
88npm install --save graphql-web-lite
89# or
90yarn add graphql-web-lite
91```
92
93To alias a package in Webpack, an entry must be added to your Webpack
94configuration's `resolve.alias` section. Depending on your implementation,
95the configuration may already contain some keys inside `resolve.alias`, and
96you'd want to add another entry for `"graphql"`.
97
98```js
99const webpackConfig = {
100 // ...
101 resolve: {
102 alias: {
103 graphql: 'graphql-web-lite',
104 },
105 },
106};
107```
108
109</details>
110
111<details>
112<summary><strong>Installation with Next.js</strong></summary>
113
114First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
115package.
116
117```sh
118npm install --save graphql-web-lite
119# or
120yarn add graphql-web-lite
121```
122
123In your [Next.js configuration file](https://nextjs.org/docs/api-reference/next.config.js/introduction),
124under `next.config.js`, you can add an additional `webpack()` function that is
125able to modify Next's Webpack configuration to add an alias for `graphql`.
126
127```js
128module.exports = {
129 webpack(config, { isServer }) {
130 if (!isServer) {
131 config.resolve.alias = {
132 ...config.resolve.alias,
133 graphql: 'graphql-web-lite',
134 };
135 }
136 return config;
137 },
138};
139```
140
141Here we're also ensuring that the alias isn't applied on the server-side, in case
142an API route is using `graphql` for a server-side GraphQL schema.
143
144</details>
145
146<details>
147<summary><strong>Installation with Rollup's alias plugin</strong></summary>
148
149First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
150package.
151
152```sh
153npm install --save graphql-web-lite
154# or
155yarn add graphql-web-lite
156```
157
158In Rollup, the easiest way to add a new alias is to use `@rollup/plugin-alias`.
159We'll have to install this plugin and ensure that every import and deep import
160to `graphql` is aliased to `graphql-web-lite`.
161
162Any Rollup-based build will fail when the import name of the package does not
163match the `name` field in the module's `package.json` file, so this step is
164necessary.
165
166```js
167import alias from '@rollup/plugin-alias';
168
169module.exports = {
170 plugins: [
171 alias({
172 entries: [{ find: 'graphql', replacement: 'graphql-web-lite' }],
173 }),
174 ],
175};
176```
177
178</details>
179
180<details>
181<summary><strong>Installation with Vite</strong></summary>
182
183First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
184package.
185
186```sh
187npm install --save graphql-web-lite
188# or
189yarn add graphql-web-lite
190```
191
192In your [Vite configuration file](https://vitejs.dev/config/#config-file-resolving)
193you may add a new entry for its `resolve.alias` entries. This entry works the same
194as Rollup's alias plugin.
195
196```js
197import { defineConfig } from 'vite';
198
199export default defineConfig({
200 resolve: {
201 alias: {
202 graphql: 'graphql-web-lite',
203 },
204 },
205});
206```
207
208Here we're also ensuring that the alias isn't applied on the server-side, in case
209an API route is using `graphql` for a server-side GraphQL schema.
210
211</details>
212
213<details>
214<summary><strong>Installation with Parcel</strong></summary>
215
216First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
217package.
218
219```sh
220npm install --save graphql-web-lite
221# or
222yarn add graphql-web-lite
223```
224
225In Parcel, we can add an entry in our `package.json` file for an alias. Specifically,
226the `alias` property may contain an object that maps packages to their aliases.
227
228```diff
229{
230 "alias": {
231+ "graphql": "graphql-web-lite"
232 }
233}
234```
235
236</details>
237
238<details>
239<summary><strong>Installation with Jest's module mapping</strong></summary>
240
241First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql`
242package.
243
244```sh
245npm install --save graphql-web-lite
246# or
247yarn add graphql-web-lite
248```
249
250Jest allows any module names to be remapped using regular expression-based
251mappings. In your Jest config you'll need to add an entry for `graphql` that
252remaps all imports and deep imports to `graphql-web-lite`.
253
254```json
255{
256 "moduleNameMapper": {
257 "graphql(.*)": "graphql-web-lite$1"
258 }
259}
260```
261
262</details>
263
264## Impact & Changes
265
266In short, most utilities, functions, and classes exported by the `graphql`
267package are only used for server-side GraphQL. Some of them have been removed
268in `graphql-web-lite` to discourage its server-side usage, and help bundlers
269exlude them if tree-shaking were to fail.
270
271Most GraphQL clients rely on importing the parser, printer, visitor, and the
272`GraphQLError` class. These have all been modified to reduce their bundlesize
273impact and to remove any support for
274[GraphQL's schema language and type system](https://spec.graphql.org/June2018/#sec-Type-System).
275
276Any debugging calls, development-time warnings, and other non-production code
277is also being transpiled away, and `process.env.NODE_ENV` has been compiled
278away.
279
280<details>
281<summary><strong>Full List of Changes</strong></summary>
282
283| Export | Changes | Notes |
284| --------------------- | ---------- | ------------------------------------------------------------------- |
285| `visit` | _modified_ | works recursively and does not detect invalid AST nodes |
286| `print` | _modified_ | won't output any schema nodes and does not detect invalid AST nodes |
287| `printLocation` | _modified_ | won't output source snippets |
288| `printSourceLocation` | _modified_ | won't output source snippets |
289| `parse` | _modified_ | won't parse schema nodes or throw precise syntax errors |
290| `parseType` | _modified_ | won't throw precise syntax errors |
291| `parseValue` | _modified_ | won't throw precise syntax errors |
292| `GraphQLError` | _modified_ | doesn't handle locations and Error stacks |
293
294</details>
295
296### Bundlesize Impact
297
298Most GraphQL client-side libraries use the following common set of imports from the `graphql` library.
299
300```js
301export { BREAK, isSelectionNode, parse, print, GraphQLError, Kind, visit } from 'graphql';
302```
303
304The minzipped size of the imports is about `10kB` in a given output bundle, which assumes all the above imports are
305in use. When `graphql-web-lite` replaces the `graphql` package the minzipped size drops to about `3kB`.