mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
Load ErrorComponent dynamically (#6171)
Closes #6152. - Only dynamically load /_error.js when an exception occurs. - Fix websocket “/_error.js” ping oddity.
This commit is contained in:
parent
8fdb133903
commit
1a416b688e
|
@ -8,7 +8,7 @@ import { loadGetInitialProps, getURL } from '../utils'
|
||||||
export default class Router {
|
export default class Router {
|
||||||
static events = mitt()
|
static events = mitt()
|
||||||
|
|
||||||
constructor (pathname, query, as, { initialProps, pageLoader, App, Component, ErrorComponent, err } = {}) {
|
constructor (pathname, query, as, { initialProps, pageLoader, App, Component, err } = {}) {
|
||||||
// represents the current component key
|
// represents the current component key
|
||||||
this.route = toRoute(pathname)
|
this.route = toRoute(pathname)
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ export default class Router {
|
||||||
// We should not keep the cache, if there's an error
|
// We should not keep the cache, if there's an error
|
||||||
// Otherwise, this cause issues when when going back and
|
// Otherwise, this cause issues when when going back and
|
||||||
// come again to the errored page.
|
// come again to the errored page.
|
||||||
if (Component !== ErrorComponent) {
|
if (pathname !== '/_error') {
|
||||||
this.components[this.route] = { Component, props: initialProps, err }
|
this.components[this.route] = { Component, props: initialProps, err }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ export default class Router {
|
||||||
this.events = Router.events
|
this.events = Router.events
|
||||||
|
|
||||||
this.pageLoader = pageLoader
|
this.pageLoader = pageLoader
|
||||||
this.ErrorComponent = ErrorComponent
|
|
||||||
this.pathname = pathname
|
this.pathname = pathname
|
||||||
this.query = query
|
this.query = query
|
||||||
this.asPath = as
|
this.asPath = as
|
||||||
|
@ -291,7 +290,7 @@ export default class Router {
|
||||||
return { error: err }
|
return { error: err }
|
||||||
}
|
}
|
||||||
|
|
||||||
const Component = this.ErrorComponent
|
const Component = await this.fetchComponent('/_error')
|
||||||
routeInfo = { Component, err }
|
routeInfo = { Component, err }
|
||||||
const ctx = { err, pathname, query }
|
const ctx = { err, pathname, query }
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -73,7 +73,6 @@ export default async ({
|
||||||
if (process.env.NODE_ENV === 'development') {
|
if (process.env.NODE_ENV === 'development') {
|
||||||
webpackHMR = passedWebpackHMR
|
webpackHMR = passedWebpackHMR
|
||||||
}
|
}
|
||||||
ErrorComponent = await pageLoader.loadPage('/_error')
|
|
||||||
App = await pageLoader.loadPage('/_app')
|
App = await pageLoader.loadPage('/_app')
|
||||||
|
|
||||||
let initialErr = err
|
let initialErr = err
|
||||||
|
@ -99,7 +98,6 @@ export default async ({
|
||||||
pageLoader,
|
pageLoader,
|
||||||
App,
|
App,
|
||||||
Component,
|
Component,
|
||||||
ErrorComponent,
|
|
||||||
err: initialErr
|
err: initialErr
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -138,6 +136,8 @@ export async function renderError (props) {
|
||||||
// Make sure we log the error to the console, otherwise users can't track down issues.
|
// Make sure we log the error to the console, otherwise users can't track down issues.
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
|
||||||
|
ErrorComponent = await pageLoader.loadPage('/_error')
|
||||||
|
|
||||||
// In production we do a normal render with the `ErrorComponent` as component.
|
// In production we do a normal render with the `ErrorComponent` as component.
|
||||||
// If we've gotten here upon initial render, we can use the props from the server.
|
// If we've gotten here upon initial render, we can use the props from the server.
|
||||||
// Otherwise, we need to call `getInitialProps` on `App` before mounting.
|
// Otherwise, we need to call `getInitialProps` on `App` before mounting.
|
||||||
|
|
|
@ -125,7 +125,6 @@ export class Head extends Component {
|
||||||
{head}
|
{head}
|
||||||
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
|
{page !== '/_error' && <link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
|
||||||
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
||||||
<link rel='preload' href={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} as='script' nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
|
||||||
{this.getPreloadDynamicChunks()}
|
{this.getPreloadDynamicChunks()}
|
||||||
{this.getPreloadMainLinks()}
|
{this.getPreloadMainLinks()}
|
||||||
{this.getCssLinks()}
|
{this.getCssLinks()}
|
||||||
|
@ -221,7 +220,6 @@ export class NextScript extends Component {
|
||||||
}} />}
|
}} />}
|
||||||
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
|
{page !== '/_error' && <script async id={`__NEXT_PAGE__${page}`} src={`${assetPrefix}/_next/static/${buildId}/pages${pagePathname}`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />}
|
||||||
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
<script async id={`__NEXT_PAGE__/_app`} src={`${assetPrefix}/_next/static/${buildId}/pages/_app.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
||||||
<script async id={`__NEXT_PAGE__/_error`} src={`${assetPrefix}/_next/static/${buildId}/pages/_error.js`} nonce={this.props.nonce} crossOrigin={this.props.crossOrigin || process.crossOrigin} />
|
|
||||||
{staticMarkup ? null : this.getDynamicChunks()}
|
{staticMarkup ? null : this.getDynamicChunks()}
|
||||||
{staticMarkup ? null : this.getScripts()}
|
{staticMarkup ? null : this.getScripts()}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|
|
@ -229,7 +229,7 @@ describe('Production Usage', () => {
|
||||||
it('should add preload tags when Link prefetch prop is used', async () => {
|
it('should add preload tags when Link prefetch prop is used', async () => {
|
||||||
const browser = await webdriver(appPort, '/prefetch')
|
const browser = await webdriver(appPort, '/prefetch')
|
||||||
const elements = await browser.elementsByCss('link[rel=preload]')
|
const elements = await browser.elementsByCss('link[rel=preload]')
|
||||||
expect(elements.length).toBe(10)
|
expect(elements.length).toBe(9)
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
elements.map(async (element) => {
|
elements.map(async (element) => {
|
||||||
const rel = await element.getAttribute('rel')
|
const rel = await element.getAttribute('rel')
|
||||||
|
|
Loading…
Reference in a new issue