# Webpack Loader

You can load GraphQL queries over `.graphql` files using Webpack. The package [`@graphql-tools/webpack-loader`](https://www.npmjs.com/package/@graphql-tools/webpack-loader) comes with a loader easy to setup and with some benefits:

1. Do not process GraphQL ASTs on client-side
2. Enable queries to be separated from logic

In the example below, we create a new file called `currentUser.graphql`:

## currentUser.graphql

```
query CurrentUserForLayout {
  currentUser {
    login
    avatar_url
  }
}
```

You can load this file adding a rule in your webpack config file:

```
rules: [\
  {\
    test: /\.(graphql|gql)$/,\
    exclude: /node_modules/,\
    loader: '@graphql-tools/webpack-loader',\
  },\
];
```

As you can see, `.graphql` or `.gql` files will be parsed whenever imported:

```
import { Apollo } from 'apollo-angular';
import { Component } from '@angular/core';
import currentUserQuery from './currentUser.graphql';

@Component({
  // ...
})
class ProfileComponent {
  constructor(apollo: Apollo) {
    apollo.query({ query: currentUserQuery }).subscribe(result => {
      // ...
    });
  }
}
```

## Optional: Install and Configure a Custom webpack Configuration (When Using Angular CLI)

Install `@angular-builders/custom-webpack`:

```
npm i @angular-builders/custom-webpack
```
```
pnpm add @angular-builders/custom-webpack
```
```
yarn add @angular-builders/custom-webpack
```
```
bun add @angular-builders/custom-webpack
```

Then create a webpack configuration file `webpack.config.js` in your application root containing your Webpack configuration (as listed above):

## webpack.config.js

```
module.exports = {
  module: {
    rules: [\
      {\
        test: /\.(graphql|gql)$/,\
        exclude: /node_modules/,\
        loader: '@graphql-tools/webpack-loader',\
      },\
    ],
  },
};
```

After that, create your type-definition for your `.graphql` files, so TypeScript will transform them into importable objects with `src/@types/graphql.d.ts`:

## graphql.d.ts

```
declare module '*.graphql' {
  import { DocumentNode } from 'graphql';
  const schema: DocumentNode;

export = schema;
}
```

Next, update your TSConfig:

## tsconfig.json

```
{
  // ...
  "files": [\
    // ...\
    "src/@types/graphql.d.ts",\
  ],
  "compilerOptions": {
    "typeRoots": [\
      // ...\
      "src/@types",\
    ],
  },
}
```

Finally, you have to manipulate your `angular.json` to accept your customized webpack configuration:

## angular.json

```
{
  // ...
  "projects": {
    "<Your project name here>": {
      // ...
      "architect": {
        "build": {
          // ...
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./webpack.config.js",
              "replaceDuplicatePlugins": true,
            },
          },
        },
        "serve": {
          // ...
          "builder": "@angular-builders/custom-webpack:dev-server",
        },
      },
    },
  },
}
```

### Jest

[Jest](https://facebook.github.io/jest/) can’t use the Webpack loaders. To make the same transformation work in Jest, use [`@graphql-tools/jest-transform`](https://npmjs.com/package/@graphql-tools/jest-transform).

## Fragments

You can use and include fragments in `.graphql` files and have webpack include those dependencies for you, similar to how you would use fragments and queries with the gql tag in plain JavaScript.

```
#import "./UserInfoFragment.graphql"

query CurrentUserForLayout {
  currentUser {
    ...UserInfo
  }
}
```

See how we import the UserInfo fragment from another `.graphql` file (same way you’d import modules in JavaScript).

And here’s an example of defining the fragment in another `.graphql` file.

```
fragment UserInfo on User {
  login
  avatar_url
}
```

Last updated on April 1, 2024
