2017-02-06 48 views
0

對於我目前的項目,我試圖創建一個通用reactjs網站。我目前的服務器架構限制了我只能使用Tomcat應用程序服務器。安裝nodejs服務器不是一個選項。Nashorn和Tomcat Universal Reactjs

作爲POC,我使用一個示例存儲庫(https://github.com/pgrimard/spring-boot-react),其中包含與在服務器上呈現的react-router相關的響應。在運行此示例時,出現以下錯誤:

org.springframework.scripting.support.StandardScriptEvalException: TypeError: 0 ,> u.createServerRenderContext is not a function in <eval> at line number 1 

此錯誤在設置react-router上下文時發生在server.js文件中。有沒有人有任何經驗,在Tomcat容器內使用更大的反應應用程序,並使用SSR?或者還有其他解決方案嗎?

在此先感謝!

回答

1

的存在,我發表了關於使用犀牛做反應SSR的文章。 https://medium.com/@jimmy_shen/use-nashorn-engine-to-do-server-side-rendering-with-react-eba835e33d77使用Nashorn Engine進行React Server-Side Rendering

關鍵是關於XmlHttpRequest和WebAPI的Nashorn的polyfill。 nashorn-polyfill將做到這一點。

而且您可能會檢查出Demo。該應用程序與React,Apollo,React-Router v4堆棧。

+0

感謝您的回覆!我已經使用您的文章進行設置。問題在於,需要提供服務器的應用程序使用react-router v3,這會導致一些問題。感謝您的幫助! –

1

我遇到了同樣的問題。

我是新來的節點,但如果你檢查node_modules文件夾,以及爲react-router v4 documentation,有一個ServerRouter類不提,像一個堪稱client.js文件。

可能是創建createServerRenderContext函數也不存在。至少不在這個模塊中。

嘗試用代替那個StaticRouter也許。

編輯:

管理,使其通過安裝最新版本ReactRouter 4測試版的

npm install --save [email protected] 
npm install --save [email protected] 

然後改變server.js文件工作:

import React from 'react'; 
import ReactDOMServer from 'react-dom/server'; 
import {StaticRouter} from 'react-router'; 
import {createStore, applyMiddleware} from 'redux'; 
import thunkMiddleware from 'redux-thunk'; 
import {Provider} from 'react-redux'; 
import serialize from 'serialize-javascript'; 
import reducer from './reducers'; 
import App from 'components/App'; 

window.render = (template, model) => { 
     const context = {}; 
     const req = JSON.parse(model.get('req')); 
     const initialState = JSON.parse(model.get('initialState')); 

     const store = createStore(reducer, initialState, applyMiddleware(thunkMiddleware)); 

     const markup = ReactDOMServer.renderToString(
     <Provider store={store}> 
      <StaticRouter location={req.location} context={context}> 
      <App/> 
      </StaticRouter> 
     </Provider> 
    ); 

     return template 
     .replace('SERVER_RENDERED_HTML', markup) 
     .replace('SERVER_RENDERED_STATE', serialize(initialState, {isJSON:true})); 
}; 

客戶端.js與:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import {BrowserRouter} from 'react-router-dom'; 
import {createStore, applyMiddleware} from 'redux'; 
import thunkMiddleware from 'redux-thunk'; 
import {Provider} from 'react-redux'; 
import reducer from './reducers'; 
import App from 'components/App'; 

const store = createStore(reducer, window.__PRELOADED_STATE__, applyMiddleware(thunkMiddleware)); 

const markup = (
    <Provider store={store}> 
    <BrowserRouter> 
     <App/> 
    </BrowserRouter> 
    </Provider> 
); 

ReactDOM.render(markup, document.getElementById('app')); 

最後的App.js

import React from 'react'; 
import {Route, Link} from 'react-router-dom'; 
import Home from 'components/Home'; 
import Child from 'components/Child'; 
import 'styles/main.css'; 

export default function App() { 
    return (
    <div> 
     <h1>Hello Server Side Rendering!!</h1> 

     <ul> 
     <li><Link to="/">{'Home'}</Link></li> 
     <li><Link to="/child">{'Child'}</Link></li> 
     </ul> 

     <Route exactly path="/" component={Home}/> 
     <Route path="/child" component={Child}/> 

    </div> 
); 
} 

我刪除了小姐的對象,因爲它沒有在這個版本的反應路由器

+0

我將來會將react-router升級到v4,然後重試此解決方案。謝謝! –