Reac-Router v4, server side rendering, ReferenceError: document is not defined
Reac-Router v4, server side rendering, ReferenceError: document is not defined
我正在使用 react-router 版本 4 并尝试处理服务器上的路由。
包括 offical Server Rendering guide on ReactTraining repo and React Router tutorial - server side rendering 在内的所有教程都使用 React Router v3。
唯一可用的指南是 Server side rendering with React Router version 4。
我按照相同的步骤操作,但出现以下错误:
_reactDom2.default.render(_react2.default.createElement(App, null), document.getElementById('app'));
^
ReferenceError: document is not defined
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:271:70)
at __webpack_require__ (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:20:30)
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:59:13)
at __webpack_require__ (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:20:30)
at /Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:40:18
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:43:10)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
这是我的网站
var fs = require('fs');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'server.js'),
output: {
filename: 'public/server.bundle.js',
},
plugins: [
new ExtractTextPlugin('public/styles.css'),
],
target: 'node',
// keep node_module paths out of the bundle
externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
'react-dom/server', 'react/addons',
]).reduce(function (ext, mod) {
ext[mod] = 'commonjs ' + mod
return ext
}, {}),
node: {
__filename: true,
__dirname: true
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
}, {
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000&name=/[hash].[ext]',
}, {
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract(['css', 'sass']),
},
],
},
}
还有我的 server.js:
import { createServer } from 'http';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { ServerRouter, createServerRenderContext } from 'react-router';
import App from './src/components/App';
createServer((req, res) => {
// first create a context for <ServerRouter>, it's where we keep the
// results of rendering for the second pass if necessary
const context = createServerRenderContext()
// render the first time
let markup = renderToString(
<ServerRouter
location={req.url}
context={context}
>
<App/>
</ServerRouter>
)
// get the result
const result = context.getResult()
// the result will tell you if it redirected, if so, we ignore
// the markup and send a proper redirect.
if (result.redirect) {
res.writeHead(301, {
Location: result.redirect.pathname
})
res.end()
} else {
// the result will tell you if there were any misses, if so
// we can send a 404 and then do a second render pass with
// the context to clue the <Miss> components into rendering
// this time (on the client they know from componentDidMount)
if (result.missed) {
res.writeHead(404)
markup = renderToString(
<ServerRouter
location={req.url}
context={context}
>
<App />
</ServerRouter>
)
}
res.write(markup)
res.end()
}
}).listen(8080)
我刚刚弄明白了!
正如@Paul S 在评论中提到的,问题来自将此链接:ReactDOM.render(<App />, document.getElementById('app'));
放在 App
组件中。
所以我刚刚创建了另一个文件 client.js 并将行移到了那里。所以它有效。
这是因为 App
组件在服务器端和客户端之间共享。所以如果你想处理服务器端渲染,你需要从 App
组件中取出客户端代码。
感谢保罗。
我已经基于 redux 服务器端渲染和 react-router v4 服务器端渲染文档创建了启动器:https://github.com/gzoreslav/react-redux-saga-universal-application
我正在使用 react-router 版本 4 并尝试处理服务器上的路由。
包括 offical Server Rendering guide on ReactTraining repo and React Router tutorial - server side rendering 在内的所有教程都使用 React Router v3。
唯一可用的指南是 Server side rendering with React Router version 4。
我按照相同的步骤操作,但出现以下错误:
_reactDom2.default.render(_react2.default.createElement(App, null), document.getElementById('app'));
^
ReferenceError: document is not defined
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:271:70)
at __webpack_require__ (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:20:30)
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:59:13)
at __webpack_require__ (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:20:30)
at /Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:40:18
at Object.<anonymous> (/Users/fakhruddinabdi/Projects/fotomantic/fotomantic.com/public/server.bundle.js:43:10)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
这是我的网站
var fs = require('fs');
var path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, 'server.js'),
output: {
filename: 'public/server.bundle.js',
},
plugins: [
new ExtractTextPlugin('public/styles.css'),
],
target: 'node',
// keep node_module paths out of the bundle
externals: fs.readdirSync(path.resolve(__dirname, 'node_modules')).concat([
'react-dom/server', 'react/addons',
]).reduce(function (ext, mod) {
ext[mod] = 'commonjs ' + mod
return ext
}, {}),
node: {
__filename: true,
__dirname: true
},
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
}, {
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2)$/,
loader: 'url-loader?limit=10000&name=/[hash].[ext]',
}, {
test: /\.scss$/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract(['css', 'sass']),
},
],
},
}
还有我的 server.js:
import { createServer } from 'http';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { ServerRouter, createServerRenderContext } from 'react-router';
import App from './src/components/App';
createServer((req, res) => {
// first create a context for <ServerRouter>, it's where we keep the
// results of rendering for the second pass if necessary
const context = createServerRenderContext()
// render the first time
let markup = renderToString(
<ServerRouter
location={req.url}
context={context}
>
<App/>
</ServerRouter>
)
// get the result
const result = context.getResult()
// the result will tell you if it redirected, if so, we ignore
// the markup and send a proper redirect.
if (result.redirect) {
res.writeHead(301, {
Location: result.redirect.pathname
})
res.end()
} else {
// the result will tell you if there were any misses, if so
// we can send a 404 and then do a second render pass with
// the context to clue the <Miss> components into rendering
// this time (on the client they know from componentDidMount)
if (result.missed) {
res.writeHead(404)
markup = renderToString(
<ServerRouter
location={req.url}
context={context}
>
<App />
</ServerRouter>
)
}
res.write(markup)
res.end()
}
}).listen(8080)
我刚刚弄明白了!
正如@Paul S 在评论中提到的,问题来自将此链接:ReactDOM.render(<App />, document.getElementById('app'));
放在 App
组件中。
所以我刚刚创建了另一个文件 client.js 并将行移到了那里。所以它有效。
这是因为 App
组件在服务器端和客户端之间共享。所以如果你想处理服务器端渲染,你需要从 App
组件中取出客户端代码。
感谢保罗。
我已经基于 redux 服务器端渲染和 react-router v4 服务器端渲染文档创建了启动器:https://github.com/gzoreslav/react-redux-saga-universal-application