我正在使用webpack @ 2和React-Router @ 4构建一个React应用程序。在开发模式下,一切正常,但对于生产,我想使用服务器端渲染,它会导致错误:
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 :(得分:0)
在Home.js和About.js
<script>
// Immediately Invoked Function Expression instead of function declaration
(function() {
var head = document.querySelector('head');
var link = document.createElement('link');
link.rel = 'stylesheet';
var theTime = new Date().getHours();
console.log (theTime);
if (theTime >= 9 && theTime < 17) {
link.href='/nuvoladigital.com.br/css/stylesDAY.css';
} else {
link.href='/nuvoladigital.com.br/css/stylesNIGHT.css';
}
head.appendChild(link);
}());
</script>
<noscript>
<link href="/nuvoladigital.com.br/css/stylesnight.css" rel="stylesheet">
</noscript>
答案 1 :(得分:0)
您要导入的链接组件来自&#39; react-router&#39;这是问题,这将适用于react-router版本&lt; 4.0。从react-router版本4开始,此Link包是react-router-dom的一部分。所以你需要先安装react-router-dom:
npm install --save react-router-dom
并像这样导入:
import { Link } from 'react-router-dom'