2016-11-22 17 views
1

私はリアクタールータバージョン4を使用しており、サーバー上のルートを処理しようとしています。Reac-Router v4、サーバーサイドレンダリング、ReferenceError:ドキュメントが定義されていません

offical Server Rendering guide on ReactTraining repoReact Router tutorial - server side renderingを含むすべてのチュートリアルでは、リアクタールーター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) 
+0

、のdocument.getElementById(「アプリ」) ); 'あなたのプロジェクトに存在しますか?サーバ上で実行されている行のために私が見ることができる唯一の理由は、それがあなたの 'App.js'ファイルにあることです。 –

+0

あなたは右のポール..それはApp.js ..に存在するが、代わりにそれを置く場所がわからない –

+0

私はちょうどclient.jsというファイルを作成し、webpackのエントリーポイントとしてそれを設定した。そこに.. あなたは正しい方法ですか? –

答えて

0

私はちょうど理解した。!

コメントに記載されているように、この問題はlinke:ReactDOM.render(<App />, document.getElementById('app'));Appコンポーネントの内側に置くことで問題になります。

私はちょうどclient.jsという別のファイルを作成し、そこに行を移動しました。それは動作します。

その理由は、Appコンポーネントがサーバー側とクライアント側で共有されているためです。したがって、サーバー側のレンダリングに対処する場合は、クライアントコードをAppコンポーネントから取り除く必要があります。

Paulに感謝します。

+0

そして、このファイルをどのようにして正確に呼び出して使用しますか? – kushalvm

+0

webpack.configのclient.jsをエントリポイントとして追加する必要があります webpackを使用していますか? –

関連する問題