我无法呈现反应服务器端。我总是得到 ^
没有定义ReferenceError:文档
var root = document.getElementById('root');
我知道什么是讨厌该节点不了解浏览器文档对象。但我似乎无法解决它。我在webpack或服务器或app.js中做错了什么。
这是我的代码
server.js
import express from 'express';
import path from 'path';
import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import configureStore from './src/store/configureStore';
import routes from './src';
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
/**
* React application route, supports server side rendering.
*/
app.get('/*', function(req, res) {
// Create a context for <StaticRouter>, which will allow us to
// query for the results of the render.
const reactRouterContext = {};
// Compile an initial state
const preloadedState = {};
// Create a new Redux store instance
const store = configureStore(preloadedState);
// Declare our React application.
const app = (
<Provider store={store}>
<StaticRouter location={req.url} context={reactRouterContext}>
{routes}
</StaticRouter>
</Provider>
);
const appString = renderToString(app);
// Load contents of index.html
fs.readFile(
path.join(__dirname, 'build', 'index.html'),
'utf8',
(err, data) => {
if (err) throw err;
// Inserts the rendered React HTML into our main div
const document = data.replace(
/<main id="root"><\/main>/,
`<main id="root">${app}</main>`
);
// Sends the response back to the client
res.status(200).send();
}
);
});
app.listen(9000);
webpack.config.node.js
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
// http://jlongster.com/Backend-Apps-with-Webpack--Part-I
let nodeModules = {};
fs
.readdirSync('node_modules')
.filter(function(f) {
return f.charAt(0) !== '.';
})
.forEach(function(f) {
nodeModules[f] = 'commonjs ' + f;
});
module.exports = {
target: 'node',
entry: './server.js',
output: {
path: path.join(__dirname, 'build'),
filename: 'server.js',
libraryTarget: 'commonjs2',
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react', 'stage-0'],
},
},
{
test: /\.css$/,
exclude: /node_modules/,
loader: 'css-loader',
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true,
},
},
],
},
],
},
plugins: [
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true),
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
}),
//new UglifyJSPlugin(),
],
externals: nodeModules,
};
最后这是我的app.js
import React from 'react';
import { hydrate, render } from 'react-dom'; // eslint-disable-line
import { Provider } from 'react-redux';
import { BrowserRouter, Route } from 'react-router-dom';
import configureStore from './store/configureStore';
import Home from './routes/home';
import Profile from './routes/profile';
import Contact from './routes/contact';
import RouterWrapper from './routeWrapper';
import './index.css';
const store = configureStore();
window.store = store;
// Does the user's browser support the HTML5 history API?
// If the user's browser doesn't support the HTML5 history API then we
// will force full page refreshes on each page change.
const supportsHistory =
window && window.history && 'pushState' in window.history ? true : false;
const routes = (
<div>
<RouterWrapper>
<Route exact path="/" component={Home} />
<Route path="/profile" component={Profile} />
<Route path="/contact" component={Contact} />
</RouterWrapper>
</div>
);
const app = (
<Provider store={store}>
<BrowserRouter forceRefresh={!supportsHistory}>{routes}</BrowserRouter>
</Provider>
);
const root = document.getElementById('root');
const renderApp = newRoot => {
if (process.env.NODE_ENV === 'development') {
render(app, newRoot);
} else {
hydrate(app, newRoot);
}
};
renderApp(root);
export default routes;
答案 0 :(得分:2)
根本原因:插件样式加载程序会将CSS输入CSS到js中以在js中生成样式标签,例如document.createelement ("style")
;但服务器没有文档api。因此它崩溃了。
尝试使用mini-css-extract-plugin
将CSS代码从js文件中拉出。
避免在js文件中使用document.creatEelement ("style")
;
发布我的配置的一部分
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: process.env.NODE_ENV === 'development' ? 'development' : 'production',
module: {
rules: [
{
test: /\.css$/,
exclude: /node_modules/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
// use: ['style-loader', 'css-loader']
}
],
},
plugins: [new MiniCssExtractPlugin()],
};
如有任何疑问,请告诉我
答案 1 :(得分:0)
只需将library(raster)
library(rasterVis)
r <- raster(system.file("external/test.grd", package="raster"))
levelplot(r, at=seq(100, 1850, by = 250))
# calculating the latitudinal means
rows <- init(r, v='y')
yAve <- zonal(r, rows, fun='mean',na.rm=TRUE)
summary(yAve)
移至其他文件即可。导入它们时,将执行整个文件,从而导致错误。
答案 2 :(得分:-1)
导入文件时,将执行文件的全部内容,包括const root = document.getElementById('root');
行。
如果您将routes
声明移到单独的文件并从那里导出,您应该能够在server.js
和app.js
中导入该文件,您应该没问题。