From bc403af001a3a9b26e75a6f3cf2a002a99de9c17 Mon Sep 17 00:00:00 2001 From: Jens Meindertsma Date: Mon, 28 Dec 2020 20:22:10 +0100 Subject: [PATCH] Update with-msw example (#20335) * Update with-msw example * Update README * Update examples/with-msw/README.md * lint fix Co-authored-by: Luis Alvarez D Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- examples/with-msw/.env.development | 1 + examples/with-msw/.env.production | 1 + examples/with-msw/README.md | 2 +- examples/with-msw/package.json | 6 ++-- examples/with-msw/pages/_app.js | 4 +-- examples/with-msw/pages/index.js | 35 ++++--------------- examples/with-msw/public/mockServiceWorker.js | 26 ++++++++------ 7 files changed, 30 insertions(+), 45 deletions(-) create mode 100644 examples/with-msw/.env.development create mode 100644 examples/with-msw/.env.production diff --git a/examples/with-msw/.env.development b/examples/with-msw/.env.development new file mode 100644 index 0000000000..629e10c5c5 --- /dev/null +++ b/examples/with-msw/.env.development @@ -0,0 +1 @@ +NEXT_PUBLIC_API_MOCKING=enabled diff --git a/examples/with-msw/.env.production b/examples/with-msw/.env.production new file mode 100644 index 0000000000..629e10c5c5 --- /dev/null +++ b/examples/with-msw/.env.production @@ -0,0 +1 @@ +NEXT_PUBLIC_API_MOCKING=enabled diff --git a/examples/with-msw/README.md b/examples/with-msw/README.md index d7c1368e46..df99517b4c 100644 --- a/examples/with-msw/README.md +++ b/examples/with-msw/README.md @@ -8,7 +8,7 @@ In this example we integrate Mock Service Worker with Next by following the next 1. Setup a [Service Worker instance](./mocks/browser.js) that would intercept all runtime client-side requests via `setupWorker` function. 1. Setup a ["server" instance](./mocks/server.js) to intercept any server/build time requests (e.g. the one happening in `getServerSideProps`) via `setupServer` function. -Mocking is enabled using the `NEXT_PUBLIC_API_MOCKING` environment variable, which for the sake of the example is saved inside `.env` instead of `.env.development`. In a real app you should move the variable to `.env.development` because mocking should only be done for development. +Mocking is enabled using the `NEXT_PUBLIC_API_MOCKING` environment variable. By default, mocking is enabled for both development and production. This allows you to have working preview deployments before implementing an actual API. To disable MSW for a specific environment, change the environment variable value in the file corresponding to the environment from `enabled` to `disabled`. ## Deploy your own diff --git a/examples/with-msw/package.json b/examples/with-msw/package.json index 967337fb22..a1749b8a95 100644 --- a/examples/with-msw/package.json +++ b/examples/with-msw/package.json @@ -8,9 +8,9 @@ }, "license": "MIT", "dependencies": { - "msw": "^0.21.2", + "msw": "^0.24.2", "next": "latest", - "react": "^16.13.1", - "react-dom": "^16.13.1" + "react": "^17.0.1", + "react-dom": "^17.0.1" } } diff --git a/examples/with-msw/pages/_app.js b/examples/with-msw/pages/_app.js index 5202969b2f..b20c39be7b 100644 --- a/examples/with-msw/pages/_app.js +++ b/examples/with-msw/pages/_app.js @@ -1,6 +1,4 @@ -// Enable API mocking in all environments except production. -// This is recommended for real-world apps. -if (process.env.NODE_ENV !== 'production') { +if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') { require('../mocks') } diff --git a/examples/with-msw/pages/index.js b/examples/with-msw/pages/index.js index 823fba68a1..f22c03b0b4 100644 --- a/examples/with-msw/pages/index.js +++ b/examples/with-msw/pages/index.js @@ -1,6 +1,6 @@ import { useState } from 'react' -export default function Home({ book, inProduction }) { +export default function Home({ book }) { const [reviews, setReviews] = useState(null) const handleGetReviews = () => { @@ -10,18 +10,6 @@ export default function Home({ book, inProduction }) { .then(setReviews) } - if (inProduction) { - return ( -
-

- This example does not work in production, as MSW is not intended for - use in production. In a real-world app, your request will hit the - actual backend instead. -

-
- ) - } - return (
{book.title} @@ -44,21 +32,12 @@ export default function Home({ book, inProduction }) { export async function getServerSideProps() { // Server-side requests are mocked by `mocks/server.js`. - // In a real-world app this request would hit the actual backend. - try { - const res = await fetch('https://my.backend/book') - const book = await res.json() + const res = await fetch('https://my.backend/book') + const book = await res.json() - return { - props: { - book, - }, - } - } catch (error) { - return { - props: { - inProduction: true, - }, - } + return { + props: { + book, + }, } } diff --git a/examples/with-msw/public/mockServiceWorker.js b/examples/with-msw/public/mockServiceWorker.js index e94d7a8f30..d4d30cc9a7 100644 --- a/examples/with-msw/public/mockServiceWorker.js +++ b/examples/with-msw/public/mockServiceWorker.js @@ -7,7 +7,7 @@ /* eslint-disable */ /* tslint:disable */ -const INTEGRITY_CHECKSUM = 'd1e0e502f550d40a34bee90822e4bf98' +const INTEGRITY_CHECKSUM = '65d33ca82955e1c5928aed19d1bdf3f9' const bypassHeaderName = 'x-msw-bypass' let clients = {} @@ -74,11 +74,22 @@ self.addEventListener('message', async function (event) { } }) -self.addEventListener('fetch', async function (event) { +self.addEventListener('fetch', function (event) { const { clientId, request } = event const requestClone = request.clone() const getOriginalResponse = () => fetch(requestClone) + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Bypass mocking if the current client isn't present in the internal clients map + // (i.e. has the mocking disabled). + if (!clients[clientId]) { + return + } + // Opening the DevTools triggers the "only-if-cached" request // that cannot be handled by the worker. Bypass such requests. if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { @@ -89,20 +100,15 @@ self.addEventListener('fetch', async function (event) { new Promise(async (resolve, reject) => { const client = await event.target.clients.get(clientId) - if ( - // Bypass mocking when no clients active - !client || - // Bypass mocking if the current client has mocking disabled - !clients[clientId] || - // Bypass mocking for navigation requests - request.mode === 'navigate' - ) { + // Bypass mocking when the request client is not active. + if (!client) { return resolve(getOriginalResponse()) } // Bypass requests with the explicit bypass header if (requestClone.headers.get(bypassHeaderName) === 'true') { const modifiedHeaders = serializeHeaders(requestClone.headers) + // Remove the bypass header to comply with the CORS preflight check delete modifiedHeaders[bypassHeaderName] -- GitLab