mirror of
https://github.com/terribleplan/next.js.git
synced 2024-01-19 02:48:18 +00:00
parent
0f9ea55023
commit
86d01706a6
|
@ -1,2 +1,3 @@
|
|||
[ignore]
|
||||
<PROJECT_ROOT>/examples/.*
|
||||
<PROJECT_ROOT>/examples/.*
|
||||
<PROJECT_ROOT>/.*.json
|
|
@ -7,7 +7,7 @@ install:
|
|||
# Install Google Chrome for e2e testing
|
||||
- choco install --ignore-checksums googlechrome
|
||||
# Get the latest stable version of Node.js or io.js
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- ps: Install-Product node $env:nodejs_version x64
|
||||
# install modules
|
||||
- npm install
|
||||
|
||||
|
|
41
client/dev-error-overlay.js
Normal file
41
client/dev-error-overlay.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import {applySourcemaps} from './source-map-support'
|
||||
import ErrorDebug, {styles} from '../lib/error-debug'
|
||||
import type {RuntimeError, ErrorReporterProps} from './error-boundary'
|
||||
|
||||
type State = {|
|
||||
mappedError: null | RuntimeError
|
||||
|}
|
||||
|
||||
// This component is only used in development, sourcemaps are applied on the fly because componentDidCatch is not async
|
||||
class DevErrorOverlay extends React.Component<ErrorReporterProps, State> {
|
||||
state = {
|
||||
mappedError: null
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
const {error} = this.props
|
||||
|
||||
// Since componentDidMount doesn't handle errors we use then/catch here
|
||||
applySourcemaps(error).then(() => {
|
||||
this.setState({mappedError: error})
|
||||
}).catch((caughtError) => {
|
||||
this.setState({mappedError: caughtError})
|
||||
})
|
||||
}
|
||||
|
||||
render () {
|
||||
const {mappedError} = this.state
|
||||
const {info} = this.props
|
||||
if (mappedError === null) {
|
||||
return <div style={styles.errorDebug}>
|
||||
<h1 style={styles.heading}>Loading stacktrace...</h1>
|
||||
</div>
|
||||
}
|
||||
|
||||
return <ErrorDebug error={mappedError} info={info} />
|
||||
}
|
||||
}
|
||||
|
||||
export default DevErrorOverlay
|
66
client/error-boundary.js
Normal file
66
client/error-boundary.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
// @flow
|
||||
import * as React from 'react'
|
||||
import {polyfill} from 'react-lifecycles-compat'
|
||||
|
||||
type ComponentDidCatchInfo = {
|
||||
componentStack: string
|
||||
}
|
||||
|
||||
export type Info = null | ComponentDidCatchInfo
|
||||
|
||||
export type RuntimeError = Error & {|
|
||||
module: ?{|
|
||||
rawRequest: string
|
||||
|}
|
||||
|}
|
||||
|
||||
export type ErrorReporterProps = {|error: RuntimeError, info: Info|}
|
||||
type ErrorReporterComponent = React.ComponentType<ErrorReporterProps>
|
||||
|
||||
type Props = {|
|
||||
ErrorReporter: null | ErrorReporterComponent,
|
||||
onError: (error: RuntimeError, info: ComponentDidCatchInfo) => void,
|
||||
children: React.ComponentType<*>
|
||||
|}
|
||||
|
||||
type State = {|
|
||||
error: null | RuntimeError,
|
||||
info: Info
|
||||
|}
|
||||
|
||||
class ErrorBoundary extends React.Component<Props, State> {
|
||||
state = {
|
||||
error: null,
|
||||
info: null
|
||||
}
|
||||
static getDerivedStateFromProps () {
|
||||
return {
|
||||
error: null,
|
||||
info: null
|
||||
}
|
||||
}
|
||||
componentDidCatch (error: RuntimeError, info: ComponentDidCatchInfo) {
|
||||
const {onError} = this.props
|
||||
|
||||
// onError is provided in production
|
||||
if (onError) {
|
||||
onError(error, info)
|
||||
} else {
|
||||
this.setState({ error, info })
|
||||
}
|
||||
}
|
||||
render () {
|
||||
const {ErrorReporter, children} = this.props
|
||||
const {error, info} = this.state
|
||||
if (ErrorReporter && error) {
|
||||
return <ErrorReporter error={error} info={info} />
|
||||
}
|
||||
|
||||
return React.Children.only(children)
|
||||
}
|
||||
}
|
||||
|
||||
// Makes sure we can use React 16.3 lifecycles and still support older versions of React.
|
||||
polyfill(ErrorBoundary)
|
||||
|
||||
export default ErrorBoundary
|
|
@ -7,6 +7,7 @@ import { loadGetInitialProps, getURL } from '../lib/utils'
|
|||
import PageLoader from '../lib/page-loader'
|
||||
import * as asset from '../lib/asset'
|
||||
import * as envConfig from '../lib/runtime-config'
|
||||
import ErrorBoundary from './error-boundary'
|
||||
|
||||
// Polyfill Promise globally
|
||||
// This is needed because Webpack2's dynamic loading(common chunks) code
|
||||
|
@ -66,8 +67,7 @@ const errorContainer = document.getElementById('__next-error')
|
|||
let lastAppProps
|
||||
export let router
|
||||
export let ErrorComponent
|
||||
let HotAppContainer
|
||||
let ErrorDebugComponent
|
||||
let DevErrorOverlay
|
||||
let Component
|
||||
let App
|
||||
let stripAnsi = (s) => s
|
||||
|
@ -76,8 +76,7 @@ let applySourcemaps = (e) => e
|
|||
export const emitter = new EventEmitter()
|
||||
|
||||
export default async ({
|
||||
HotAppContainer: passedHotAppContainer,
|
||||
ErrorDebugComponent: passedDebugComponent,
|
||||
DevErrorOverlay: passedDevErrorOverlay,
|
||||
stripAnsi: passedStripAnsi,
|
||||
applySourcemaps: passedApplySourcemaps
|
||||
} = {}) => {
|
||||
|
@ -88,8 +87,7 @@ export default async ({
|
|||
|
||||
stripAnsi = passedStripAnsi || stripAnsi
|
||||
applySourcemaps = passedApplySourcemaps || applySourcemaps
|
||||
HotAppContainer = passedHotAppContainer
|
||||
ErrorDebugComponent = passedDebugComponent
|
||||
DevErrorOverlay = passedDevErrorOverlay
|
||||
ErrorComponent = await pageLoader.loadPage('/_error')
|
||||
App = await pageLoader.loadPage('/_app')
|
||||
|
||||
|
@ -115,12 +113,12 @@ export default async ({
|
|||
err: initialErr
|
||||
})
|
||||
|
||||
router.subscribe(({ Component, props, hash, err }) => {
|
||||
render({ Component, props, err, hash, emitter })
|
||||
router.subscribe(({ App, Component, props, hash, err }) => {
|
||||
render({ App, Component, props, err, hash, emitter })
|
||||
})
|
||||
|
||||
const hash = location.hash.substring(1)
|
||||
render({ Component, props, hash, err: initialErr, emitter })
|
||||
render({ App, Component, props, hash, err: initialErr, emitter })
|
||||
|
||||
return emitter
|
||||
}
|
||||
|
@ -143,14 +141,14 @@ export async function render (props) {
|
|||
// 404 and 500 errors are special kind of errors
|
||||
// and they are still handle via the main render method.
|
||||
export async function renderError (props) {
|
||||
const {err} = props
|
||||
const {err, errorInfo} = props
|
||||
|
||||
// In development we apply sourcemaps to the error
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
await applySourcemaps(err)
|
||||
}
|
||||
|
||||
const str = stripAnsi(`${err.message}\n${err.stack}${err.info ? `\n\n${err.info.componentStack}` : ''}`)
|
||||
const str = stripAnsi(`${err.message}\n${err.stack}${errorInfo ? `\n\n${errorInfo.componentStack}` : ''}`)
|
||||
console.error(str)
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
|
@ -159,7 +157,7 @@ export async function renderError (props) {
|
|||
// Otherwise, we need to face issues when the issue is fixed and
|
||||
// it's get notified via HMR
|
||||
ReactDOM.unmountComponentAtNode(appContainer)
|
||||
renderReactElement(<ErrorDebugComponent error={err} />, errorContainer)
|
||||
renderReactElement(<DevErrorOverlay error={err} />, errorContainer)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -168,7 +166,7 @@ export async function renderError (props) {
|
|||
await doRender({...props, err, Component: ErrorComponent})
|
||||
}
|
||||
|
||||
async function doRender ({ Component, props, hash, err, emitter: emitterProp = emitter }) {
|
||||
async function doRender ({ App, Component, props, hash, err, emitter: emitterProp = emitter }) {
|
||||
// Usual getInitialProps fetching is handled in next/router
|
||||
// this is for when ErrorComponent gets replaced by Component by HMR
|
||||
if (!props && Component &&
|
||||
|
@ -190,15 +188,25 @@ async function doRender ({ Component, props, hash, err, emitter: emitterProp = e
|
|||
// We need to clear any existing runtime error messages
|
||||
ReactDOM.unmountComponentAtNode(errorContainer)
|
||||
|
||||
// In development we render react-hot-loader's wrapper component
|
||||
if (HotAppContainer) {
|
||||
renderReactElement(<HotAppContainer errorReporter={ErrorDebugComponent} warnings={false}>
|
||||
<App {...appProps} />
|
||||
</HotAppContainer>, appContainer)
|
||||
} else {
|
||||
renderReactElement(<App {...appProps} />, appContainer)
|
||||
let onError = null
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
onError = async (error, errorInfo) => {
|
||||
try {
|
||||
await renderError({App, err: error, errorInfo})
|
||||
} catch (err) {
|
||||
console.error('Error while rendering error page: ', err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In development we render a wrapper component that catches runtime errors.
|
||||
renderReactElement((
|
||||
<ErrorBoundary ErrorReporter={DevErrorOverlay} onError={onError}>
|
||||
<App {...appProps} />
|
||||
</ErrorBoundary>
|
||||
), appContainer)
|
||||
|
||||
emitterProp.emit('after-reactdom-render', { Component, ErrorComponent, appProps })
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import stripAnsi from 'strip-ansi'
|
||||
import initNext, * as next from './'
|
||||
import {ClientDebug} from '../lib/error-debug'
|
||||
import DevErrorOverlay from './dev-error-overlay'
|
||||
import initOnDemandEntries from './on-demand-entries-client'
|
||||
import initWebpackHMR from './webpack-hot-middleware-client'
|
||||
import {AppContainer as HotAppContainer} from 'react-hot-loader'
|
||||
import {applySourcemaps} from './source-map-support'
|
||||
|
||||
window.next = next
|
||||
|
||||
initNext({ HotAppContainer, ErrorDebugComponent: ClientDebug, applySourcemaps, stripAnsi })
|
||||
initNext({ DevErrorOverlay, applySourcemaps, stripAnsi })
|
||||
.then((emitter) => {
|
||||
initOnDemandEntries()
|
||||
initWebpackHMR()
|
||||
|
|
53
flow-typed/npm/react-lifecycles-compat_vx.x.x.js
vendored
Normal file
53
flow-typed/npm/react-lifecycles-compat_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
// flow-typed signature: 729d832efcac0a21ab881042caf78e1e
|
||||
// flow-typed version: <<STUB>>/react-lifecycles-compat_v3.0.4/flow_v0.73.0
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'react-lifecycles-compat'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'react-lifecycles-compat' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.cjs' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.es' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.min' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.cjs.js' {
|
||||
declare module.exports: $Exports<'react-lifecycles-compat/react-lifecycles-compat.cjs'>;
|
||||
}
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.es.js' {
|
||||
declare module.exports: $Exports<'react-lifecycles-compat/react-lifecycles-compat.es'>;
|
||||
}
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.js' {
|
||||
declare module.exports: $Exports<'react-lifecycles-compat/react-lifecycles-compat'>;
|
||||
}
|
||||
declare module 'react-lifecycles-compat/react-lifecycles-compat.min.js' {
|
||||
declare module.exports: $Exports<'react-lifecycles-compat/react-lifecycles-compat.min'>;
|
||||
}
|
123
flow-typed/npm/source-map_vx.x.x.js
vendored
Normal file
123
flow-typed/npm/source-map_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,123 @@
|
|||
// flow-typed signature: 4307ae4d07743816402f6fe06ed629ad
|
||||
// flow-typed version: <<STUB>>/source-map_v0.5.7/flow_v0.73.0
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'source-map'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'source-map' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'source-map/dist/source-map.debug' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/dist/source-map' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/dist/source-map.min' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/array-set' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/base64-vlq' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/base64' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/binary-search' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/mapping-list' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/quick-sort' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/source-map-consumer' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/source-map-generator' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/source-node' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/lib/util' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'source-map/source-map' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'source-map/dist/source-map.debug.js' {
|
||||
declare module.exports: $Exports<'source-map/dist/source-map.debug'>;
|
||||
}
|
||||
declare module 'source-map/dist/source-map.js' {
|
||||
declare module.exports: $Exports<'source-map/dist/source-map'>;
|
||||
}
|
||||
declare module 'source-map/dist/source-map.min.js' {
|
||||
declare module.exports: $Exports<'source-map/dist/source-map.min'>;
|
||||
}
|
||||
declare module 'source-map/lib/array-set.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/array-set'>;
|
||||
}
|
||||
declare module 'source-map/lib/base64-vlq.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/base64-vlq'>;
|
||||
}
|
||||
declare module 'source-map/lib/base64.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/base64'>;
|
||||
}
|
||||
declare module 'source-map/lib/binary-search.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/binary-search'>;
|
||||
}
|
||||
declare module 'source-map/lib/mapping-list.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/mapping-list'>;
|
||||
}
|
||||
declare module 'source-map/lib/quick-sort.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/quick-sort'>;
|
||||
}
|
||||
declare module 'source-map/lib/source-map-consumer.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/source-map-consumer'>;
|
||||
}
|
||||
declare module 'source-map/lib/source-map-generator.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/source-map-generator'>;
|
||||
}
|
||||
declare module 'source-map/lib/source-node.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/source-node'>;
|
||||
}
|
||||
declare module 'source-map/lib/util.js' {
|
||||
declare module.exports: $Exports<'source-map/lib/util'>;
|
||||
}
|
||||
declare module 'source-map/source-map.js' {
|
||||
declare module.exports: $Exports<'source-map/source-map'>;
|
||||
}
|
60
flow-typed/npm/unfetch_vx.x.x.js
vendored
Normal file
60
flow-typed/npm/unfetch_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// flow-typed signature: a652d8adeb137f15eeb79e87d8238710
|
||||
// flow-typed version: <<STUB>>/unfetch_v3.0.0/flow_v0.73.0
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'unfetch'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'unfetch' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'unfetch/dist/unfetch.es' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'unfetch/dist/unfetch' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'unfetch/dist/unfetch.umd' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'unfetch/polyfill' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'unfetch/src/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'unfetch/dist/unfetch.es.js' {
|
||||
declare module.exports: $Exports<'unfetch/dist/unfetch.es'>;
|
||||
}
|
||||
declare module 'unfetch/dist/unfetch.js' {
|
||||
declare module.exports: $Exports<'unfetch/dist/unfetch'>;
|
||||
}
|
||||
declare module 'unfetch/dist/unfetch.umd.js' {
|
||||
declare module.exports: $Exports<'unfetch/dist/unfetch.umd'>;
|
||||
}
|
||||
declare module 'unfetch/polyfill.js' {
|
||||
declare module.exports: $Exports<'unfetch/polyfill'>;
|
||||
}
|
||||
declare module 'unfetch/src/index.js' {
|
||||
declare module.exports: $Exports<'unfetch/src/index'>;
|
||||
}
|
102
flow-typed/npm/webpack-sources_vx.x.x.js
vendored
Normal file
102
flow-typed/npm/webpack-sources_vx.x.x.js
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
// flow-typed signature: d41ce38862b325831cb20e57893195bc
|
||||
// flow-typed version: <<STUB>>/webpack-sources_v1.1.0/flow_v0.73.0
|
||||
|
||||
/**
|
||||
* This is an autogenerated libdef stub for:
|
||||
*
|
||||
* 'webpack-sources'
|
||||
*
|
||||
* Fill this stub out by replacing all the `any` types.
|
||||
*
|
||||
* Once filled out, we encourage you to share your work with the
|
||||
* community by sending a pull request to:
|
||||
* https://github.com/flowtype/flow-typed
|
||||
*/
|
||||
|
||||
declare module 'webpack-sources' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
/**
|
||||
* We include stubs for each file inside this npm package in case you need to
|
||||
* require those files directly. Feel free to delete any files that aren't
|
||||
* needed.
|
||||
*/
|
||||
declare module 'webpack-sources/lib/CachedSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/ConcatSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/index' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/LineToLineMappedSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/OriginalSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/PrefixSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/RawSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/ReplaceSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/Source' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/SourceAndMapMixin' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
declare module 'webpack-sources/lib/SourceMapSource' {
|
||||
declare module.exports: any;
|
||||
}
|
||||
|
||||
// Filename aliases
|
||||
declare module 'webpack-sources/lib/CachedSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/CachedSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/ConcatSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/ConcatSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/index.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/index'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/LineToLineMappedSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/LineToLineMappedSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/OriginalSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/OriginalSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/PrefixSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/PrefixSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/RawSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/RawSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/ReplaceSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/ReplaceSource'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/Source.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/Source'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/SourceAndMapMixin.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/SourceAndMapMixin'>;
|
||||
}
|
||||
declare module 'webpack-sources/lib/SourceMapSource.js' {
|
||||
declare module.exports: $Exports<'webpack-sources/lib/SourceMapSource'>;
|
||||
}
|
16
lib/app.js
16
lib/app.js
|
@ -27,18 +27,10 @@ export default class App extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
componentDidCatch (err, info) {
|
||||
// To provide clearer stacktraces in error-debug.js in development
|
||||
// To provide clearer stacktraces in app.js in production
|
||||
err.info = info
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// In production we render _error.js
|
||||
window.next.renderError({err})
|
||||
} else {
|
||||
// In development we throw the error up to AppContainer from react-hot-loader
|
||||
throw err
|
||||
}
|
||||
// Kept here for backwards compatibility.
|
||||
// When someone ended App they could call `super.componentDidCatch`. This is now deprecated.
|
||||
componentDidCatch (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
render () {
|
||||
|
|
|
@ -1,43 +1,12 @@
|
|||
// @flow
|
||||
import React from 'react'
|
||||
import ansiHTML from 'ansi-html'
|
||||
import Head from './head'
|
||||
import {applySourcemaps} from '../client/source-map-support'
|
||||
import type {ErrorReporterProps} from '../client/error-boundary'
|
||||
|
||||
// On the client side the error can come from multiple places for example react-hot-loader or client/index.js
|
||||
// `componentDidCatch` doesn't support asynchronous execution, so we have to handle sourcemap support here
|
||||
export class ClientDebug extends React.Component {
|
||||
state = {
|
||||
mappedError: null
|
||||
}
|
||||
componentDidMount () {
|
||||
const {error} = this.props
|
||||
|
||||
// If sourcemaps were already applied there is no need to set the state
|
||||
if (error.sourceMapsApplied) {
|
||||
return
|
||||
}
|
||||
|
||||
// Since componentDidMount doesn't handle errors we use then/catch here
|
||||
applySourcemaps(error).then(() => {
|
||||
this.setState({mappedError: error})
|
||||
}).catch(console.error)
|
||||
}
|
||||
|
||||
render () {
|
||||
const {mappedError} = this.state
|
||||
const {error} = this.props
|
||||
if (!error.sourceMapsApplied && mappedError === null) {
|
||||
return <div style={styles.errorDebug}>
|
||||
<h1 style={styles.heading}>Loading stacktrace...</h1>
|
||||
</div>
|
||||
}
|
||||
|
||||
return <ErrorDebug error={error} />
|
||||
}
|
||||
}
|
||||
|
||||
// On the server side the error has sourcemaps already applied, so `ErrorDebug` is rendered directly.
|
||||
export default function ErrorDebug ({error}) {
|
||||
// This component is rendered through dev-error-overlay on the client side.
|
||||
// On the server side it's rendered directly
|
||||
export default function ErrorDebug ({error, info}: ErrorReporterProps) {
|
||||
const { name, message, module } = error
|
||||
return (
|
||||
<div style={styles.errorDebug}>
|
||||
|
@ -46,15 +15,15 @@ export default function ErrorDebug ({error}) {
|
|||
</Head>
|
||||
{module ? <h1 style={styles.heading}>Error in {module.rawRequest}</h1> : null}
|
||||
{
|
||||
name === 'ModuleBuildError'
|
||||
name === 'ModuleBuildError' && message
|
||||
? <pre style={styles.stack} dangerouslySetInnerHTML={{ __html: ansiHTML(encodeHtml(message)) }} />
|
||||
: <StackTrace error={error} />
|
||||
: <StackTrace error={error} info={info} />
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const StackTrace = ({ error: { name, message, stack, info } }) => (
|
||||
const StackTrace = ({ error: { name, message, stack }, info }: ErrorReporterProps) => (
|
||||
<div>
|
||||
<div style={styles.heading}>{message || name}</div>
|
||||
<pre style={styles.stack}>
|
||||
|
@ -66,7 +35,7 @@ const StackTrace = ({ error: { name, message, stack, info } }) => (
|
|||
</div>
|
||||
)
|
||||
|
||||
const styles = {
|
||||
export const styles = {
|
||||
errorDebug: {
|
||||
background: '#0e0d0d',
|
||||
boxSizing: 'border-box',
|
||||
|
|
|
@ -28,12 +28,13 @@ export default class Router {
|
|||
this.components[this.route] = { Component, props: initialProps, err }
|
||||
}
|
||||
|
||||
this.components['/_app'] = { Component: App }
|
||||
|
||||
// Handling Router Events
|
||||
this.events = new EventEmitter()
|
||||
|
||||
this.pageLoader = pageLoader
|
||||
this.prefetchQueue = new PQueue({ concurrency: 2 })
|
||||
this.App = App
|
||||
this.ErrorComponent = ErrorComponent
|
||||
this.pathname = pathname
|
||||
this.query = query
|
||||
|
@ -352,8 +353,9 @@ export default class Router {
|
|||
let cancelled = false
|
||||
const cancel = () => { cancelled = true }
|
||||
this.componentLoadCancel = cancel
|
||||
const {Component: App} = this.components['/_app']
|
||||
|
||||
const props = await loadGetInitialProps(this.App, {Component, router: this, ctx})
|
||||
const props = await loadGetInitialProps(App, {Component, router: this, ctx})
|
||||
|
||||
if (cancel === this.componentLoadCancel) {
|
||||
this.componentLoadCancel = null
|
||||
|
@ -381,7 +383,8 @@ export default class Router {
|
|||
}
|
||||
|
||||
notify (data) {
|
||||
this.subscriptions.forEach((fn) => fn(data))
|
||||
const {Component: App} = this.components['/_app']
|
||||
this.subscriptions.forEach((fn) => fn({...data, App}))
|
||||
}
|
||||
|
||||
subscribe (fn) {
|
||||
|
|
|
@ -34,9 +34,10 @@
|
|||
"testonly": "cross-env NODE_PATH=test/lib jest \\.test.js",
|
||||
"posttestonly": "taskr posttest",
|
||||
"testall": "npm run testonly -- --coverage --forceExit --runInBand --verbose --bail",
|
||||
"pretest": "npm run lint",
|
||||
"pretest": "npm run lint && npm run flow",
|
||||
"test": "cross-env npm run testall || npm run testall",
|
||||
"coveralls": "nyc --instrument=false --source-map=false report --temp-directory=./coverage --reporter=text-lcov | coveralls",
|
||||
"flow": "flow check",
|
||||
"lint": "standard 'bin/*' 'client/**/*.js' 'examples/**/*.js' 'lib/**/*.js' 'pages/**/*.js' 'server/**/*.js' 'test/**/*.js'",
|
||||
"prepublish": "npm run release",
|
||||
"precommit": "lint-staged"
|
||||
|
@ -88,6 +89,7 @@
|
|||
"prop-types": "15.6.0",
|
||||
"prop-types-exact": "1.1.1",
|
||||
"react-hot-loader": "4.1.3",
|
||||
"react-lifecycles-compat": "3.0.4",
|
||||
"recursive-copy": "2.0.6",
|
||||
"resolve": "1.5.0",
|
||||
"send": "0.16.1",
|
||||
|
@ -126,6 +128,7 @@
|
|||
"cross-env": "5.0.5",
|
||||
"express": "4.15.5",
|
||||
"fkill": "5.1.0",
|
||||
"flow-bin": "0.73.0",
|
||||
"get-port": "3.2.0",
|
||||
"husky": "0.14.3",
|
||||
"jest-cli": "21.2.0",
|
||||
|
@ -135,8 +138,8 @@
|
|||
"node-fetch": "1.7.3",
|
||||
"node-notifier": "5.1.2",
|
||||
"nyc": "11.2.1",
|
||||
"react": "16.2.0",
|
||||
"react-dom": "16.2.0",
|
||||
"react": "16.4.0",
|
||||
"react-dom": "16.4.0",
|
||||
"rimraf": "2.6.2",
|
||||
"standard": "11.0.1",
|
||||
"taskr": "1.1.0",
|
||||
|
|
|
@ -2,7 +2,6 @@ import babelLoader from 'babel-loader'
|
|||
|
||||
module.exports = babelLoader.custom(babel => {
|
||||
const presetItem = babel.createConfigItem(require('../babel/preset'), {type: 'preset'})
|
||||
const hotLoaderItem = babel.createConfigItem(require('react-hot-loader/babel'), {type: 'plugin'})
|
||||
const reactJsxSourceItem = babel.createConfigItem(require('@babel/plugin-transform-react-jsx-source'), {type: 'plugin'})
|
||||
|
||||
const configs = new Set()
|
||||
|
@ -38,7 +37,6 @@ module.exports = babelLoader.custom(babel => {
|
|||
|
||||
options.plugins = [
|
||||
...options.plugins,
|
||||
dev && !isServer && hotLoaderItem,
|
||||
dev && reactJsxSourceItem
|
||||
].filter(Boolean)
|
||||
|
||||
|
|
|
@ -177,7 +177,6 @@ export default async function getBaseWebpackConfig (dir, {dev = false, isServer
|
|||
// required not to cache removed files
|
||||
useHashIndex: false
|
||||
}),
|
||||
!dev && new webpack.IgnorePlugin(/react-hot-loader/),
|
||||
!isServer && !dev && new UglifyJSPlugin({
|
||||
exclude: /react\.js/,
|
||||
parallel: true,
|
||||
|
|
20
yarn.lock
20
yarn.lock
|
@ -3166,6 +3166,10 @@ flatten@^1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
flow-bin@0.73.0:
|
||||
version "0.73.0"
|
||||
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.73.0.tgz#da1b90a02b0ef9c439f068c2fc14968db83be425"
|
||||
|
||||
flush-write-stream@^1.0.0:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd"
|
||||
|
@ -6132,9 +6136,9 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7:
|
|||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-dom@16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.2.0.tgz#69003178601c0ca19b709b33a83369fe6124c044"
|
||||
react-dom@16.4.0:
|
||||
version "16.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.4.0.tgz#099f067dd5827ce36a29eaf9a6cdc7cbf6216b1e"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.1.0"
|
||||
|
@ -6152,13 +6156,17 @@ react-hot-loader@4.1.3:
|
|||
react-lifecycles-compat "^3.0.2"
|
||||
shallowequal "^1.0.2"
|
||||
|
||||
react-lifecycles-compat@3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
|
||||
react-lifecycles-compat@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.2.tgz#7279047275bd727a912e25f734c0559527e84eff"
|
||||
|
||||
react@16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.2.0.tgz#a31bd2dab89bff65d42134fa187f24d054c273ba"
|
||||
react@16.4.0:
|
||||
version "16.4.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.4.0.tgz#402c2db83335336fba1962c08b98c6272617d585"
|
||||
dependencies:
|
||||
fbjs "^0.8.16"
|
||||
loose-envify "^1.1.0"
|
||||
|
|
Loading…
Reference in a new issue