2016-12-15 9 views
0

Ich habe eine Anwendung mit Webpack als Modul Bundler und Babel als meine js Compiler konfiguriert. alles auf einer Knoten-Engine. Ich stellte fest, dass, wenn ich renne npm run dev der folgende Ablauf wird:ReactDOM.renderToString sessionStorage ist nicht definiert, Fenster ist nicht definiert

Die webpack-dev-server.js wird ausgeführt. die Datei ist die folgende:

const Express = require('express'); 
const webpack = require('webpack'); 
const webpackConfig = require('./dev.config'); 
const compiler = webpack(webpackConfig); 

const host = 'localhost'; 
const port = 8080; 
const serverOptions = { 
    contentBase: `http://${host}:${port}`, 
    quiet: true, 
    noInfo: true, 
    hot: true, 
    inline: true, 
    lazy: false, 
    publicPath: webpackConfig.output.publicPath, 
    headers: { 'Access-Control-Allow-Origin': '*' }, 
    stats: { colors: true }, 
}; 

const app = new Express(); 

app.use(require('webpack-dev-middleware')(compiler, serverOptions)); 
app.use(require('webpack-hot-middleware')(compiler)); 

app.listen(port, function onAppListening(err) { 
    if (err) { 
    console.error(err); 
    } else { 
    console.info('==> Webpack development server listening on port %s', port); 
    } 
}); 

Dann wird der server.js

require('./../server.babel'); 
const path = require('path'); 
const WebpackIsomorphicTools = require('webpack-isomorphic-tools'); 
const rootDir = path.resolve(require('../server/config').rootDir); 

global.__CLIENT__ = false; 
global.__SERVER__ = true; 
global.__DEVELOPMENT__ = process.env.NODE_ENV !== 'production'; 

if (__DEVELOPMENT__) { 
    if (!require('piping')({ 
    hook: true, 
    ignore: /(\/\.|~$|\.json|\.scss$)/i 
    })) { 
    return; 
    } 
} 

global.webpackIsomorphicTools = new WebpackIsomorphicTools(require('../webpack/webpack-isomorphic-tools')) 
    .development(__DEVELOPMENT__) 
    .server(rootDir,() => { 
    require('../server/server'); 
    }); 

Express- und React Rendering:

import 'babel-polyfill'; 
// Server 
import express from 'express'; 
import session from 'express-session'; 
import cookieParser from 'cookie-parser'; 
// React 
import React from 'react'; 
import ReactDOM from 'react-dom/server'; 
import createHistory from 'react-router/lib/createMemoryHistory'; 
import { match } from 'react-router'; 
// Redux 
import { Provider } from 'react-redux'; 
import { ReduxAsyncConnect, loadOnServer } from 'redux-connect'; 
import { syncHistoryWithStore } from 'react-router-redux'; 
import path from 'path'; 
import csurf from 'csurf'; 
import bodyParser from 'body-parser'; 
// Relative imports 
import Html from '../shared/html'; 
import proxy from './proxy'; 
import createStore from '../shared/redux/create'; 
import { staticPath } from './config'; 
import { getRoutes } from '../shared/routes'; 

require('dotenv').config({ 
    path: path.resolve(__dirname, '../.env'), 
}); 

const SERVER_PORT = process.env.SERVER_PORT; 
const APP_SECRET = process.env.APP_SECRET; 
const API_PORT = process.env.API_PORT; 
const API_HOST = process.env.API_HOST; 

function renderPage({ renderProps, store, res, client, csrfToken }) { 
    loadOnServer({ ...renderProps, store, helpers: { client } }) 
    .then(() => { 
     const component = (
     <Provider store={store} key="provider"> 
      <ReduxAsyncConnect {...renderProps} /> 
     </Provider> 
    ); 
     res.status(200); 
     res.send('<!doctype html>\n' + 
     ReactDOM.renderToString(
      <Html 
      assets={webpackIsomorphicTools.assets()} 
      component={component} 
      csrfToken={csrfToken} 
      store={store} 
      />, 
     ), 
    ); 
    }) 
    .catch((err) => { 
     console.error(err.stack); 
    }); 
} 


const app = express(); 
const csrf = csurf(); 

// express middlewares 
// app.use(favicon(path.resolve(__dirname, '../static/favicon.ico'))); @TODO favicon @ilanus 
app.use(bodyParser.json()); 
app.use(express.static(staticPath)); 
app.use(cookieParser(APP_SECRET)); 
app.use(session({ 
    secret: APP_SECRET, 
    saveUninitialized: true, 
    resave: true, 
})); 
app.use(csrf); 
app.use('/api', (req, res) => { 
    if (!req.xhr) res.redirect('/'); 
    proxy.web(req, res, { target: `http://${API_HOST}:${API_PORT}` }); 
}); 
app.use((req, res) => { 
    const csrfToken = req.csrfToken(); 
    if (__DEVELOPMENT__) { 
    // Do not cache webpack stats: the script file would change since 
    // hot module replacement is enabled in the development env 
    webpackIsomorphicTools.refresh(); 
    } 
    const memoryHistory = createHistory(req.originalUrl); 
    const store = createStore({}, memoryHistory); 
    const history = syncHistoryWithStore(memoryHistory, store); 
    match({ history, routes: getRoutes(store), location: req.originalUrl }, 
    (error, redirectLocation, renderProps) => { 
     if (redirectLocation) { 
     res.redirect(redirectLocation.pathname + redirectLocation.search); 
     } else if (error) { 
     console.error('ROUTER ERROR:', error); 
     res.status(500); 
     } else if (renderProps) { 
     renderPage({ renderProps, store, res, csrfToken }); 
     } else { 
     res.status(404).send('Not found'); 
     } 
    }); 
}); 

app.use((err, req, res) => { 
    if (err === 'EBADCSRFTOKEN') { 
    res.status(403); 
    res.send('invalid csrf token'); 
    } else { 
    res.status(500); 
    res.send('Oops, internal server error'); 
    } 
}); 

app.listen(SERVER_PORT, (error) => { 
    if (error) { 
    console.error(error); 
    } else { 
    console.info(`App started listening on port ${SERVER_PORT}`); 
    } 
}); 

Nun, wenn ich console.log('window', window, 'sessionStorage', sessionStorage); innerhalb einer render() Funktion oder componentDidMount() eines versuchen zu reagieren Komponente Ich habe am Ende: sessionStorage is not defined, window is not defined Fehler. Ich schätze, das liegt daran, dass ich den Stack auf der Serverseite laufen lasse und die dort nicht verfügbar sind. Was fehlt mir?

Antwort

0

Sie brauchen nur eine Funktion statt Fenster und Fenstereigenschaften für den Zugriff direkt, zB

function globalObj(){ 
    const isNode = typeof process === 'object' && process.versions && !!process.versions.node; 

    return isNode ? global : window; 
} 

können Sie den Zugriff session usw. von dort in einer universellen Weise ohne Fehler

globalObj()["sessionStorage"] 

Ich hoffe, dass hilft.