1
0
Fork 0
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:
Sultan Tarimo 2019-01-31 23:45:36 +03:00 committed by Tim Neutkens
parent 8fdb133903
commit 1a416b688e
4 changed files with 6 additions and 9 deletions

View file

@ -8,7 +8,7 @@ import { loadGetInitialProps, getURL } from '../utils'
export default class Router {
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
this.route = toRoute(pathname)
@ -17,7 +17,7 @@ export default class Router {
// We should not keep the cache, if there's an error
// Otherwise, this cause issues when when going back and
// come again to the errored page.
if (Component !== ErrorComponent) {
if (pathname !== '/_error') {
this.components[this.route] = { Component, props: initialProps, err }
}
@ -28,7 +28,6 @@ export default class Router {
this.events = Router.events
this.pageLoader = pageLoader
this.ErrorComponent = ErrorComponent
this.pathname = pathname
this.query = query
this.asPath = as
@ -291,7 +290,7 @@ export default class Router {
return { error: err }
}
const Component = this.ErrorComponent
const Component = await this.fetchComponent('/_error')
routeInfo = { Component, err }
const ctx = { err, pathname, query }
try {

View file

@ -73,7 +73,6 @@ export default async ({
if (process.env.NODE_ENV === 'development') {
webpackHMR = passedWebpackHMR
}
ErrorComponent = await pageLoader.loadPage('/_error')
App = await pageLoader.loadPage('/_app')
let initialErr = err
@ -99,7 +98,6 @@ export default async ({
pageLoader,
App,
Component,
ErrorComponent,
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.
console.error(err)
ErrorComponent = await pageLoader.loadPage('/_error')
// 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.
// Otherwise, we need to call `getInitialProps` on `App` before mounting.

View file

@ -125,7 +125,6 @@ export class Head extends Component {
{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} />}
<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.getPreloadMainLinks()}
{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} />}
<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.getScripts()}
</Fragment>

View file

@ -229,7 +229,7 @@ describe('Production Usage', () => {
it('should add preload tags when Link prefetch prop is used', async () => {
const browser = await webdriver(appPort, '/prefetch')
const elements = await browser.elementsByCss('link[rel=preload]')
expect(elements.length).toBe(10)
expect(elements.length).toBe(9)
await Promise.all(
elements.map(async (element) => {
const rel = await element.getAttribute('rel')