DEV Community

Cover image for 🚧 Configure MSW in NX
Andrew
Andrew

Posted on • Updated on

🚧 Configure MSW in NX

Mock Service Worker (MSW) is an API mocking library for browser and Node.
β€” https://mswjs.io/


Nx is a set of extensible dev tools for monorepos, which helps you develop like Google, Facebook, and Microsoft.
β€” https://nx.dev/


To get started with nx just execute

yarn create nx-workspace
Enter fullscreen mode Exit fullscreen mode

And it will assist you to setup your monorepo.

After you are done with monorepo setup, go into that directory and install msw

yarn add --dev msw
Enter fullscreen mode Exit fullscreen mode

msw is using a service worker that handles all requests. Execute bellow command to to generate a service worker file that will be loaded in your app.

yarn msw init apps/your-app-name/src
Enter fullscreen mode Exit fullscreen mode

Now you should have a new file in your repo

apps/your-app-name/src/mockServiceWorker.js
Enter fullscreen mode Exit fullscreen mode

Next step is to include this file in our app assets.
Open your workspace.json file and find assets array located at this path

/projects/your-app-name/architect/build/options/assets
Enter fullscreen mode Exit fullscreen mode

and include msw created file in assets array

{
  "projects": {
    "your-app-name": {
      "architect": {
        "build": {
          "options": {
            "assets": [
              "apps/your-app-name/src/favicon.ico",
              "apps/your-app-name/src/assets",
              "apps/your-app-name/src/mockServiceWorker.js"
            ]
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Now we have to create a file where we will create all our request handlers. This file will be created at this location.

apps/your-app-name/src/mocks.ts
Enter fullscreen mode Exit fullscreen mode

And add some handler in mocks.ts

import { setupWorker, rest } from 'msw';

const myResourceHandler = rest.get('/api/my-resource', (req, res, ctx) =>
  res(
    ctx.status(200),
    ctx.json({
      items: [],
    }),
  ),
);

const worker = setupWorker(myResourceHandler);

worker.start();
Enter fullscreen mode Exit fullscreen mode

To hook msw into our app, open file

apps/your-app-name/src/main.ts
# or main.tsx if you are using React
apps/your-app-name/src/main.tsx
Enter fullscreen mode Exit fullscreen mode

And import mocks.ts at the top of the file

import './mocks';
// ...
Enter fullscreen mode Exit fullscreen mode

Start the app

yarn start --open
Enter fullscreen mode Exit fullscreen mode

Now if you will make a fetch request to /api/my-resource you will get the response that was configured in mocks.ts

await fetch('/api/my-resource').then(res => res.json())
Enter fullscreen mode Exit fullscreen mode

This should be your response.

{
  "items": []
}
Enter fullscreen mode Exit fullscreen mode

We are almost done. msw is not recommended to be used in production. We have to do some changes to workspace.json so this service worker will be included only in development mode.

Find this location in workspace.json

/projects/your-app-name/architect/build/configurations/production
Enter fullscreen mode Exit fullscreen mode

Duplicate assets array from /projects/your-app-name/architect/build/options/assets and exclude mockServiceWorker.js file

{
  "projects": {
    "your-app-name": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "assets": [
                "apps/your-app-name/src/favicon.ico",
                "apps/your-app-name/src/assets"
              ]
            }
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Last thing we have to do, is to exclude mocks.ts file from production.

Create a new empty file mocks.prod.ts, and in production this empty file will replace mocks.ts using fileReplacements option

Find in workspace.json, array fileReplacements located at

/projects/your-app-name/architect/build/configurations/production/fileReplacements
Enter fullscreen mode Exit fullscreen mode

And add a new replacement for our files.

{
  "projects": {
    "your-app-name": {
      "architect": {
        "build": {
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "apps/your-app-name/src/environments/environment.ts",
                  "with": "apps/your-app-name/src/environments/environment.prod.ts"
                },
                {
                  "replace": "apps/your-app-name/src/mocks.ts",
                  "with": "apps/your-app-name/src/mocks.prod.ts"
                }
              ]
            }
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

We are done. Enjoy your monorepo setup.

Discussion (3)

Collapse
nareshjbhatia profile image
Naresh Bhatia

Very useful article @iamandrewluca . I was able to get my Nx app running with MSW without any issues. Also got Jest to recognize MSW.

However, having trouble with Storybook. It seems to find the handlers but has trouble loading mockServiceWorker.js. Here's the error message:

MSW Error

Any idea what could be going wrong? Here's my repo. yarn storybook:app to start storybook, then try CartView or CatalogView. You will see "Network Error".

TIA.

Collapse
iamandrewluca profile image
Andrew Author

When your run storybook, it starts standalone without app/lib configuration even if is run through nx.
Your current configuration is specifically for react-test-shop.
You will need to configure msw separately for storybook I think. Take a look at this addon, maybe it will help

storybook.js.org/addons/msw-storyb...

Collapse
nareshjbhatia profile image
Naresh Bhatia

Thanks for your response, Andrew. I will take a look. Without Nx in the picture, I have never had to do anything more than starting MSW from .storybook/preview.tsx. For example, in this repo I have the same app working with CRA and Storybook and everything works just fine!!!