-
Notifications
You must be signed in to change notification settings - Fork 194
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Only prefetch in production and in dev with process.env.SERVICE_WORKE… (
#83) * Only prefetch in production and in dev with process.env.SERVICE_WORKER set to true. * bump version * Always send version when fetching * Support Request as the first parameter to patched fetch.
- Loading branch information
1 parent
a382c65
commit e6ab35f
Showing
10 changed files
with
232 additions
and
79 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
/** | ||
* The query param that is added to fetch alls to /api routes to ensure that | ||
* cached results from previous versions of the app are not served to new versions | ||
* of the app. | ||
*/ | ||
export const VERSION_PARAM = '__v__' | ||
|
||
/** | ||
* Adds the next build id as the __v__ query parameter to the given url | ||
* @param {String} url Any URL | ||
* @return {URL} | ||
*/ | ||
export default function addVersion(url) { | ||
/* istanbul ignore next */ | ||
if (typeof window === 'undefined') return new URL(url, 'http://throwaway.api') | ||
|
||
const parsed = new URL(url, window.location.href) | ||
|
||
if (!parsed.searchParams.has(VERSION_PARAM) && typeof __NEXT_DATA__ !== 'undefined') { | ||
parsed.searchParams.append(VERSION_PARAM, __NEXT_DATA__.buildId) | ||
} | ||
|
||
return parsed | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,11 @@ | ||
import addVersion from './addVersion' | ||
|
||
/** | ||
* Returns the API URL for the given page | ||
* @param {String} pageURI The page URI | ||
* @return {String} | ||
*/ | ||
export default function getAPIURL(pageURI) { | ||
const parsed = new URL(pageURI, 'http://throwaway.com') | ||
|
||
if (typeof __NEXT_DATA__ !== 'undefined') { | ||
parsed.searchParams.append('__v__', __NEXT_DATA__.buildId) | ||
} | ||
|
||
const parsed = addVersion(pageURI) | ||
return '/api' + parsed.pathname.replace(/\/$/, '') + parsed.search | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,35 @@ | ||
let fetch = require('isomorphic-unfetch') | ||
import addVersion from './api/addVersion' | ||
|
||
// Here we patch fetch and XMLHttpRequest to always add version parameter to api calls so that cached results | ||
// from previous versions of the app aren't served to new versions. | ||
/* istanbul ignore else */ | ||
if (typeof window !== 'undefined') { | ||
const originalFetch = window.fetch | ||
|
||
window.fetch = function rsfVersionedFetch(url, init) { | ||
if (url.url) { | ||
// the first param can be a request object | ||
url = new Request(addVersion(url.url).toString(), url) | ||
} else { | ||
url = addVersion(url).toString() | ||
} | ||
|
||
return originalFetch(url, init) | ||
} | ||
} | ||
|
||
/* istanbul ignore else */ | ||
if (typeof XMLHttpRequest !== 'undefined') { | ||
const originalOpen = XMLHttpRequest.prototype.open | ||
|
||
XMLHttpRequest.prototype.open = function rsfVersionedOpen(method, url, ...others) { | ||
return originalOpen.call(this, method, addVersion(url).toString(), ...others) | ||
} | ||
} | ||
|
||
/** | ||
* An isomorphic implementation of the fetch API. You should always use this to fetch data on both the client and server. | ||
* When making requests to /api routes, ?__v__={next_build_id} will always be added to ensure that cached results | ||
* from previous versions of the app aren't served to new versions. | ||
*/ | ||
export default fetch | ||
export default require('isomorphic-unfetch') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import addVersion from '../../src/api/addVersion' | ||
|
||
describe('addVersion', () => { | ||
beforeEach(() => { | ||
window.__NEXT_DATA__ = { | ||
buildId: 'development', | ||
} | ||
}) | ||
|
||
afterEach(() => { | ||
delete window.__NEXT_DATA__ | ||
}) | ||
|
||
it('should add the version query param', () => { | ||
expect(addVersion('/foo').toString()).toBe('http://localhost/foo?__v__=development') | ||
}) | ||
|
||
it('should not duplicate the version query param', () => { | ||
expect(addVersion('/foo?__v__=1').toString()).toBe('http://localhost/foo?__v__=1') | ||
}) | ||
|
||
it('should leave the original hostname intact', () => { | ||
expect(addVersion('http://foo.com/foo').toString()).toBe('http://foo.com/foo?__v__=development') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,41 @@ | ||
describe('fetch', () => { | ||
let f, fetch | ||
let f, fetch, originalOpen, originalFetch | ||
|
||
beforeEach(() => { | ||
f = jest.fn() | ||
jest.doMock('isomorphic-unfetch', () => f) | ||
fetch = require('../src/fetch').default | ||
jest.isolateModules(() => { | ||
f = jest.fn() | ||
jest.doMock('isomorphic-unfetch', () => f) | ||
originalOpen = jest.spyOn(XMLHttpRequest.prototype, 'open') | ||
originalFetch = jest.spyOn(window, 'fetch').mockImplementation() | ||
fetch = require('../src/fetch').default | ||
window.__NEXT_DATA__ = { | ||
buildId: 'development', | ||
} | ||
}) | ||
}) | ||
|
||
afterEach(() => { | ||
delete window.__NEXT_DATA__ | ||
}) | ||
|
||
it('should export isomorphic-unfetch for backwards compatibility', () => { | ||
fetch('/foo') | ||
expect(f).toHaveBeenCalledWith('/foo') | ||
}) | ||
|
||
it('should patch window.fetch', () => { | ||
window.fetch('/foo') | ||
expect(originalFetch).toHaveBeenCalledWith('http://localhost/foo?__v__=development', undefined) | ||
}) | ||
|
||
it('should accept a request object as the first parameter', () => { | ||
window.fetch(new Request('/foo')) | ||
expect(originalFetch.mock.calls[0][0].url).toBe('http://localhost/foo?__v__=development') | ||
}) | ||
|
||
it('should add the version to XMLHttpRequest.open', () => { | ||
const req = new XMLHttpRequest() | ||
req.open('GET', '/foo') | ||
expect(originalOpen).toHaveBeenCalledWith('GET', 'http://localhost/foo?__v__=development') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.