0

Я создаю приложение React с помощью webpack @ 2 и React-Router @ 4. В режиме разработки все работает нормально, но для производства я хочу использовать боковой рендеринг сервера и это приводит меня к ошибке:React-router 4 с рендерингом на стороне сервера: TypeError: невозможно прочитать свойство «путь» от нуля

TypeError: Cannot read property 'pathname' of null 
    at isActive (/react-app/node_modules/react-router/Link.js:120:46) 
    at Object.children (/react-app/node_modules/react-router/Link.js:80:24) 
    at Subscriber.render (/react-app/node_modules/react-broadcast/Subscriber.js:65:23) 
    at /react-app/build/app.js:18:2455 
    at s (/react-app/build/app.js:17:22003) 
    at x._renderValidatedComponentWithoutOwnerOrContext (/react-app/build/app.js:18:2433) 
    at x._renderValidatedComponent (/react-app/build/app.js:18:2741) 
    at x.performInitialMount (/react-app/build/app.js:17:28173) 
    at x.mountComponent (/react-app/build/app.js:17:26586) 
    at Object.s.mountComponent (/react-app/build/app.js:1:27885) 

Вот мой App компонент:

import React from 'react'; 
import { render } from 'react-dom'; 
import { Match, Miss, Link } from 'react-router'; 

import Home from './Home'; 
import About from './About'; 
import NoMatch from './NoMatch'; 

export default() => (
    <div> 
    <ul> 
     <li><Link to="/">Home</Link></li> 
     <li><Link to="/about">About</Link></li> 
    </ul> 

    <hr/> 

    <Match exactly pattern="/" component={Home} /> 
    <Match pattern="/about" component={About} /> 

    <Miss component={NoMatch}/> 
    </div> 
); 

Вот точка входа для WebPack :

import React from 'react'; 
import express from 'express'; 
import morgan from 'morgan'; 
import path from 'path'; 
import { ServerRouter, createServerRenderContext } from 'react-router'; 
import { renderToString } from 'react-dom/server'; 

import App from './components/App'; 

const app = express(); 

app.use(morgan('combined')); 
app.use(express.static(path.join(__dirname))); 

app.set('view engine', 'pug'); 
app.set('views', path.join(__dirname, '../src/views')); 

app.get('*', function(req, res) { 
    const context = createServerRenderContext(); 

    let markup = renderToString(
    <ServerRouter 
     location={req.url} 
     context={context} 
    > 
     <App/> 
    </ServerRouter> 
); 

    const result = context.getResult(); 

    if (result.redirect) { 
    res.writeHead(301, { 
     Location: result.redirect.pathname 
    }); 

    res.end(); 
    } else { 
    if (result.missed) { 
     res.writeHead(404); 

     markup = renderToString(
     <ServerRouter 
      location={req.url} 
      context={context} 
     > 
      <App/> 
     </ServerRouter> 
    ); 

    const result = context.getResult(); 

    if (result.redirect) { 
    res.writeHead(301, { 
     Location: result.redirect.pathname 
    }); 

    res.end(); 
    } else { 
    if (result.missed) { 
     res.writeHead(404); 

     markup = renderToString(
     <ServerRouter 
      location={req.url} 
      context={context} 
     > 
      <App/> 
     </ServerRouter> 
    ); 
    } 

    res.render('index', { includeCss: true, reactMarkup: renderToString(<App />) }); 
    res.end(); 
    } 
}); 

app.listen(3000); 

И, наконец, WebPack в конфигурации:

const fs = require('fs'); 
const path = require('path'); 
const webpack = require('webpack'); 

const config = { 
    target: 'node', 

    entry: [ 
    path.join(__dirname, 'src/js/server.prod.js') 
    ], 

    output: { 
    path: path.join(__dirname, 'build'), 
    filename: 'app.js' 
    }, 

    resolve: { 
    extensions: ['.js', '.jsx'] 
    }, 

    module: { 
    rules: [ 
     { 
     test: /\.jsx?$/, 
     loader: 'babel-loader', 
     exclude: /node_modules/ 
     }, 

     { 
     test: /\.(eot|png|svg|ttf|woff|woff2)$/, 
     use: 'file-loader' 
     } 
    ] 
    }, 

    externals: fs.readdirSync('node_modules').reduce(function(acc, mod) { 
    if (mod === '.bin') { 
     return acc; 
    } 

    acc[mod] = 'commonjs ' + mod; 
    return acc; 
    }, {}), 

    node: { 
    console: false, 
    global: false, 
    process: false, 
    Buffer: false, 
    __filename: false, 
    __dirname: false, 
    }, 

    plugins: [ 
    new webpack.optimize.UglifyJsPlugin() 
    ], 

    bail: true 
}; 

module.exports = config; 

Любые идеи?

ответ

0

В Home.js и About.js

import { Link } from 'react-router'; 
0

Компонент Link вы импортируете от «реагировать-маршрутизатор» это проблема, это будет работать для реагировать маршрутизаторами версии < 4.0. Начиная с версии 4-го маршрутизатора, этот пакет Link является частью реакции-маршрутизатора-dom. Таким образом, вы должны установить реагировать-маршрутизатор-дом первым:

npm install --save react-router-dom 

и импорта, как это:

import { Link } from 'react-router-dom'