未验证 提交 bc403af0 编写于 作者: J Jens Meindertsma 提交者: GitHub

Update with-msw example (#20335)

* Update with-msw example

* Update README

* Update examples/with-msw/README.md

* lint fix
Co-authored-by: NLuis Alvarez D <luis@vercel.com>
Co-authored-by: Nkodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
上级 d434f1dd
NEXT_PUBLIC_API_MOCKING=enabled
NEXT_PUBLIC_API_MOCKING=enabled
...@@ -8,7 +8,7 @@ In this example we integrate Mock Service Worker with Next by following the next ...@@ -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 [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. 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 ## Deploy your own
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"msw": "^0.21.2", "msw": "^0.24.2",
"next": "latest", "next": "latest",
"react": "^16.13.1", "react": "^17.0.1",
"react-dom": "^16.13.1" "react-dom": "^17.0.1"
} }
} }
// Enable API mocking in all environments except production. if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
// This is recommended for real-world apps.
if (process.env.NODE_ENV !== 'production') {
require('../mocks') require('../mocks')
} }
......
import { useState } from 'react' import { useState } from 'react'
export default function Home({ book, inProduction }) { export default function Home({ book }) {
const [reviews, setReviews] = useState(null) const [reviews, setReviews] = useState(null)
const handleGetReviews = () => { const handleGetReviews = () => {
...@@ -10,18 +10,6 @@ export default function Home({ book, inProduction }) { ...@@ -10,18 +10,6 @@ export default function Home({ book, inProduction }) {
.then(setReviews) .then(setReviews)
} }
if (inProduction) {
return (
<div>
<p>
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.
</p>
</div>
)
}
return ( return (
<div> <div>
<img src={book.imageUrl} alt={book.title} width="250" /> <img src={book.imageUrl} alt={book.title} width="250" />
...@@ -44,21 +32,12 @@ export default function Home({ book, inProduction }) { ...@@ -44,21 +32,12 @@ export default function Home({ book, inProduction }) {
export async function getServerSideProps() { export async function getServerSideProps() {
// Server-side requests are mocked by `mocks/server.js`. // Server-side requests are mocked by `mocks/server.js`.
// In a real-world app this request would hit the actual backend. const res = await fetch('https://my.backend/book')
try { const book = await res.json()
const res = await fetch('https://my.backend/book')
const book = await res.json()
return { return {
props: { props: {
book, book,
}, },
}
} catch (error) {
return {
props: {
inProduction: true,
},
}
} }
} }
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
/* eslint-disable */ /* eslint-disable */
/* tslint:disable */ /* tslint:disable */
const INTEGRITY_CHECKSUM = 'd1e0e502f550d40a34bee90822e4bf98' const INTEGRITY_CHECKSUM = '65d33ca82955e1c5928aed19d1bdf3f9'
const bypassHeaderName = 'x-msw-bypass' const bypassHeaderName = 'x-msw-bypass'
let clients = {} let clients = {}
...@@ -74,11 +74,22 @@ self.addEventListener('message', async function (event) { ...@@ -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 { clientId, request } = event
const requestClone = request.clone() const requestClone = request.clone()
const getOriginalResponse = () => fetch(requestClone) 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 // Opening the DevTools triggers the "only-if-cached" request
// that cannot be handled by the worker. Bypass such requests. // that cannot be handled by the worker. Bypass such requests.
if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') {
...@@ -89,20 +100,15 @@ self.addEventListener('fetch', async function (event) { ...@@ -89,20 +100,15 @@ self.addEventListener('fetch', async function (event) {
new Promise(async (resolve, reject) => { new Promise(async (resolve, reject) => {
const client = await event.target.clients.get(clientId) const client = await event.target.clients.get(clientId)
if ( // Bypass mocking when the request client is not active.
// Bypass mocking when no clients active if (!client) {
!client ||
// Bypass mocking if the current client has mocking disabled
!clients[clientId] ||
// Bypass mocking for navigation requests
request.mode === 'navigate'
) {
return resolve(getOriginalResponse()) return resolve(getOriginalResponse())
} }
// Bypass requests with the explicit bypass header // Bypass requests with the explicit bypass header
if (requestClone.headers.get(bypassHeaderName) === 'true') { if (requestClone.headers.get(bypassHeaderName) === 'true') {
const modifiedHeaders = serializeHeaders(requestClone.headers) const modifiedHeaders = serializeHeaders(requestClone.headers)
// Remove the bypass header to comply with the CORS preflight check // Remove the bypass header to comply with the CORS preflight check
delete modifiedHeaders[bypassHeaderName] delete modifiedHeaders[bypassHeaderName]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册