我已经工作了几天,使用react,react-router和webpack的混合来启动和运行静态站点样板。不幸的是,我一直很难找到错误的来源。要生成我正在运行webpack --progress --colors --display-error-details --bail
的静态页面,这会导致以下输出(可能在渲染时发出反应警告):
90% optimize assetsWarning: Failed propType: Required prop `router` was not specified in `RouterContext`.
Warning: Failed propType: Required prop `location` was not specified in `RouterContext`.
Warning: Failed propType: Required prop `routes` was not specified in `RouterContext`.
Warning: Failed propType: Required prop `params` was not specified in `RouterContext`.
Warning: Failed propType: Required prop `components` was not specified in `RouterContext`.
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Warning: [react-router] `<RouterContext>` expects a `router` rather than a `history`
Hash: 6666e7e25ed1cee9bca3
Version: webpack 1.13.0
Time: 2189ms
Asset Size Chunks Chunk Names
production.min.js 2.33 MB 0 [emitted] router
sitemap.xml 549 bytes [emitted]
+ 245 hidden modules
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
ERROR in TypeError: Cannot read property 'listenBeforeLeavingRoute' of undefined
at getChildContext (eval at <anonymous> (router:471:2), <anonymous>:80:35)
at ReactCompositeComponentMixin._processChildContext (eval at <anonymous> (router:1143:2), <anonymous>:413:53)
at ReactCompositeComponentMixin.performInitialMount (eval at <anonymous> (router:1143:2), <anonymous>:297:127)
at ReactCompositeComponentMixin.mountComponent (eval at <anonymous> (router:1143:2), <anonymous>:222:21)
at wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
at Object.ReactReconciler.mountComponent (eval at <anonymous> (router:795:2), <anonymous>:39:35)
at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (eval at <anonymous> (router:1119:2), <anonymous>:203:44)
at ReactDOMComponent.Mixin._createContentMarkup (eval at <anonymous> (router:957:2), <anonymous>:593:32)
at ReactDOMComponent.Mixin.mountComponent (eval at <anonymous> (router:957:2), <anonymous>:478:29)
at ReactDOMComponent.wrapper [as mountComponent] (eval at <anonymous> (router:789:2), <anonymous>:66:21)
我的webpack.config.babel.js
import path from 'path'
import webpack from 'webpack'
import SiteMapPlugin from 'sitemap-webpack-plugin'
import ExtractTextPlugin from 'extract-text-webpack-plugin'
import StaticSiteGeneratorWebpackPlugin from 'static-site-generator-webpack-plugin'
const locals = {}
const paths = [
'/',
'/Simon',
'/Pomodoro',
'/TicTacToe',
'/Calculator',
'/404.html',
]
export default {
devtool: 'eval-source-map',
entry: {
router: "./src/router"
},
output: {
path: './dist',
publicPath: '/',
libraryTarget: 'umd',
filename: 'production.min.js'
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: [
'babel-preset-es2016',
'babel-preset-react',
'babel-preset-stage-0'
]
}
},
{
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader!resolve-url-loader!sass-loader')
}
]
},
plugins: [
new StaticSiteGeneratorWebpackPlugin("router", paths, locals),
new ExtractTextPlugin("production.min.css", {allChunks: true}),
new SiteMapPlugin("http://Travmatth.github.io/react-static-site", paths),
new webpack.NoErrorsPlugin()
],
resolve: {
extensions: ['', '.js', '.jsx', '.es6']
}
}
Router.jsx:
import React from 'react'
import Index from './Index'
import routes from './routes'
import ReactDOM from 'react-dom'
import ReactDOMServer from 'react-dom/server'
import {Router, RouterContext, match, browserHistory, createMemoryHistory} from 'react-router'
const createElement = (Component, props) => {
return <Component {...props} />
}
if (typeof document !== "undefined") {
ReactDOM.render((
<Router createElement={createElement} history={browserHistory}>
{routes}
</Router>),
document.getElementById('app'))
}
export default ({assets, path}, callback) => {
const location = createMemoryHistory().createLocation(path)
match({routes, location}, (err, redirectLocation, renderProps) => {
if (err) {
throw new Error(err)
}
const html = ReactDOMServer.renderToStaticMarkup(
<Index assets={assets}>
<RouterContext {...renderProps} />
</Index>
)
callback(null, `<!DOCTYPE html>${html}`)
})
}
Routes.jsx:
import React from 'react'
import Index from './Index'
import Simon from './Components/Simon'
import Landing from './Components/Landing'
import Pomodoro from './Components/Pomodoro'
import NotFound from './Components/NotFound'
import TicTacToe from './Components/TicTacToe'
import Calculator from './Components/Calculator'
import {IndexRoute, Route, Router} from 'react-router'
const routes = (
<Router>
<Route path="/" components={Index}>
<IndexRoute components={Landing}/>
<Route path="/Simon" components={Simon}/>
<Route path="/Pomodoro" components={Pomodoro}/>
<Route path="/TicTacToe" components={TicTacToe}/>
<Route path="/Calculator " components={Calculator}/>
<Route path="*" components={NotFound}/>
</Route>
</Router>
)
export {routes};
Index.jsx:
import React from 'react'
import {Link} from 'react-router'
import HTMLDocument from 'react-html-document'
export default class Index extends React.Component {
render() {
const metatags = [
{
name: 'viewport',
content: 'maximum-scale=1,' +
'initial-scale=1,' +
'width=device-width'
},
{
name: 'content-type',
content: 'text/html; charset=utf-8'
}
]
const scripts = [ '/production.min.js' ]
const stylesheets = ["/production.min.css"]
return (
<HTMLDocument title="A sensible react static site"
stylesheets={stylesheets}
metatags={metatags}
scripts={scripts}>
<div id="app">
{this.props.children}
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/Simon">Simon</Link></li>
<li><Link to="/Pomodoro">Pomodoro</Link></li>
<li><Link to="/TicTacToe">TicTacToe</Link></li>
<li><Link to="/Calculator">Calculator</Link></li>
</ul>
</div>
</HTMLDocument>
)
}
}
所有其他相关文件和目录结构可在此处找到:github。我希望有人看到类似的问题或有建议,以了解更多有关故障的信息。