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` is an **experimental** library, providing an alias package that can 25be swapped in for the standard `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 29## Installation 30 31`graphql-web-lite` mirrors the folder structure of the regular `graphql` package and 32includes mostly the same files and imports as the `graphql` package, minus a couple 33that aren't commonly used for client-side GraphQL. 34This offers us several installation options, depending on how the package is aliased 35to the regular `"graphql"` import. 36 37<details> 38<summary><strong>Installation with <code>package.json</code> aliases</strong></summary> 39 40When your dependencies and `node_modules` folder isn't used by a _GraphQL server_ and 41only used by a _GraphQL clients_, you can use a quick and easy npm installation alias. 42In your `package.json` file you can define your `graphql` installation to use 43`graphql-web-lite` instead, which is supported by both Yarn and npm: 44 45```diff 46{ 47 "dependencies": { 48- "graphql": "^15.5.0" 49+ "graphql": "npm:graphql-web-lite@^15.5.1001" 50 } 51} 52``` 53 54Alternatively, you can run an installation command to alias the package:<br /> 55 56```sh 57npm install --save graphql@npm:graphql-web-lite 58# or 59yarn add graphql@npm:graphql-web-lite 60``` 61 62When this isn't suitable — for instance, because the same dependencies are shared 63with an API or server-side GraphQL consumer, or you're working inside a monorepo — 64you can try one of the other aliasing techniques below. 65 66</details> 67 68<details> 69<summary><strong>Installation with Webpack aliases</strong></summary> 70 71First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 72package. 73 74```sh 75npm install --save graphql-web-lite 76# or 77yarn add graphql-web-lite 78``` 79 80To alias a package in Webpack, an entry must be added to your Webpack 81configuration's `resolve.alias` section. Depending on your implementation, 82the configuration may already contain some keys inside `resolve.alias`, and 83you'd want to add another entry for `"graphql"`. 84 85```js 86const webpackConfig = { 87 // ... 88 resolve: { 89 alias: { 90 graphql: 'graphql-web-lite', 91 }, 92 }, 93}; 94``` 95 96</details> 97 98<details> 99<summary><strong>Installation with Next.js</strong></summary> 100 101First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 102package. 103 104```sh 105npm install --save graphql-web-lite 106# or 107yarn add graphql-web-lite 108``` 109 110In your [Next.js configuration file](https://nextjs.org/docs/api-reference/next.config.js/introduction), 111under `next.config.js`, you can add an additional `webpack()` function that is 112able to modify Next's Webpack configuration to add an alias for `graphql`. 113 114```js 115module.exports = { 116 webpack(config, { isServer }) { 117 if (!isServer) { 118 config.resolve.alias = { 119 ...config.resolve.alias, 120 graphql: 'graphql-web-lite', 121 }; 122 } 123 return config; 124 }, 125}; 126``` 127 128Here we're also ensuring that the alias isn't applied on the server-side, in case 129an API route is using `graphql` for a server-side GraphQL schema. 130 131</details> 132 133<details> 134<summary><strong>Installation with Rollup's alias plugin</strong></summary> 135 136First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 137package. 138 139```sh 140npm install --save graphql-web-lite 141# or 142yarn add graphql-web-lite 143``` 144 145In Rollup, the easiest way to add a new alias is to use `@rollup/plugin-alias`. 146We'll have to install this plugin and ensure that every import and deep import 147to `graphql` is aliased to `graphql-web-lite`. 148 149Any Rollup-based build will fail when the import name of the package does not 150match the `name` field in the module's `package.json` file, so this step is 151necessary. 152 153```js 154import alias from '@rollup/plugin-alias'; 155 156module.exports = { 157 plugins: [ 158 alias({ 159 entries: [{ find: 'graphql', replacement: 'graphql-web-lite' }], 160 }), 161 ], 162}; 163``` 164 165</details> 166 167<details> 168<summary><strong>Installation with Vite</strong></summary> 169 170First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 171package. 172 173```sh 174npm install --save graphql-web-lite 175# or 176yarn add graphql-web-lite 177``` 178 179In your [Vite configuration file](https://vitejs.dev/config/#config-file-resolving) 180you may add a new entry for its `resolve.alias` entries. This entry works the same 181as Rollup's alias plugin. 182 183```js 184import { defineConfig } from 'vite'; 185 186export default defineConfig({ 187 resolve: { 188 alias: { 189 graphql: 'graphql-web-lite', 190 }, 191 }, 192}); 193``` 194 195Here we're also ensuring that the alias isn't applied on the server-side, in case 196an API route is using `graphql` for a server-side GraphQL schema. 197 198</details> 199 200<details> 201<summary><strong>Installation with Parcel</strong></summary> 202 203First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 204package. 205 206```sh 207npm install --save graphql-web-lite 208# or 209yarn add graphql-web-lite 210``` 211 212In Parcel, we can add an entry in our `package.json` file for an alias. Specifically, 213the `alias` property may contain an object that maps packages to their aliases. 214 215```diff 216{ 217 "alias": { 218+ "graphql": "graphql-web-lite" 219 } 220} 221``` 222 223</details> 224 225<details> 226<summary><strong>Installation with Jest's module mapping</strong></summary> 227 228First, we'll need to install `graphql-web-lite` _alongside_ the regular `graphql` 229package. 230 231```sh 232npm install --save graphql-web-lite 233# or 234yarn add graphql-web-lite 235``` 236 237Jest allows any module names to be remapped using regular expression-based 238mappings. In your Jest config you'll need to add an entry for `graphql` that 239remaps all imports and deep imports to `graphql-web-lite`. 240 241```json 242{ 243 "moduleNameMapper": { 244 "graphql(.*)": "graphql-web-lite$1" 245 } 246} 247``` 248 249</details> 250 251## Impact & Changes 252 253In short, most utilities, functions, and classes exported by the `graphql` 254package are only used for server-side GraphQL. Some of them have been removed 255in `graphql-web-lite` to discourage its server-side usage, and help bundlers 256exlude them if tree-shaking were to fail. 257 258Most GraphQL clients rely on importing the parser, printer, visitor, and the 259`GraphQLError` class. These have all been modified to reduce their bundlesize 260impact and to remove any support for 261[GraphQL's schema language and type system](https://spec.graphql.org/June2018/#sec-Type-System). 262 263Any debugging calls, development-time warnings, and other non-production code 264is also being transpiled away, and `process.env.NODE_ENV` has been compiled 265away. 266 267<details> 268<summary><strong>Full List of Changes</strong></summary> 269 270| Export | Changes | Notes | 271| -------------------------- | ----------- | ------------------------------------------------------------------- | 272| `getVisitFn` | _unchanged_ | n/a | 273| `visitInParallel` | _unchanged_ | n/a | 274| `BREAK` | _unchanged_ | n/a | 275| `visit` | _modified_ | works recursively and does not detect invalid AST nodes | 276| `print` | _modified_ | won't output any schema nodes and does not detect invalid AST nodes | 277| `printLocation` | _modified_ | won't output source snippets | 278| `printSourceLocation` | _modified_ | won't output source snippets | 279| `parse` | _modified_ | won't parse schema nodes or throw precise syntax errors | 280| `parseType` | _modified_ | won't throw precise syntax errors | 281| `parseValue` | _modified_ | won't throw precise syntax errors | 282| `GraphQLError` | _modified_ | doesn't handle locations and Error stacks | 283| `syntaxError` | _removed_ | n/a | 284| `printType` | _removed_ | n/a | 285| `printSchema` | _removed_ | n/a | 286| `printIntrospectionSchema` | _removed_ | n/a | 287| `lexicographicSortSchema` | _removed_ | n/a | 288| `isSchema` | _removed_ | n/a | 289| `isInterfaceType` | _removed_ | n/a | 290| `getDescription` | _removed_ | n/a | 291| `findDeprecatedUsages` | _removed_ | n/a | 292| `buildSchema` | _removed_ | n/a | 293| `buildASTSchema` | _removed_ | n/a | 294| `assertSchema` | _removed_ | n/a | 295| `assertInterfaceType` | _removed_ | n/a | 296| `assertCompositeType` | _removed_ | n/a | 297| `assertAbstractType` | _removed_ | n/a | 298| `TokenKind` | _removed_ | n/a | 299| `Token` | _removed_ | n/a | 300| `Lexer` | _removed_ | n/a | 301| `GraphQLUnionType` | _removed_ | n/a | 302| `GraphQLInterfaceType` | _removed_ | n/a | 303| `GraphQLInputObjectType` | _removed_ | n/a | 304 305</details> 306 307### Bundlesize Impact 308 309Most GraphQL client-side libraries use the following common set of imports from the `graphql` library. 310Assuming a transformation like [`babel-plugin-modular-graphql`](https://github.com/kitten/babel-plugin-modular-graphql/) 311or granular imports in general this creates a short list of utilities. 312 313```js 314export { valueFromASTUntyped } from 'graphql/utilities/valueFromASTUntyped.mjs'; 315export { GraphQLError } from 'graphql/error/GraphQLError.mjs'; 316export { Kind } from 'graphql/language/kinds.mjs'; 317export { parse } from 'graphql/language/parser.mjs'; 318export { print } from 'graphql/language/printer.mjs'; 319export { visit } from 'graphql/language/visitor.mjs'; 320``` 321 322The minzipped size of the imports is about `11.2kB` in a given output bundle, which assumes all the above imports are 323in use. When the GraphQL language parser is dropped from the bundle, for instance by precompiling queries and excluding 324it in a compilation step, the resulting minzipped size drops to `5.55kB`. 325 326When `graphql-web-lite` replaces the `graphql` package the minzipped size drops from the `11.2kB` figure down to `5.44kB`, 327and `3.19kB` without the parser.