2017-02-17 33 views
1

ReactJSで初めてのサーバサイドレンダリングを構築しようとしています。コードを基にしましたthis Redux tutorialReactJSサーバサイドレンダリング(webpack-dev-server)

npm start(​​)を実行しているときに、アプリケーションが正常に動作しています。

dev環境でアプリケーションを高速デバッグできるようにするために、ホットリロードを使用したいと考えています。そこで、私はnpm構成(webpack-dev-server --inline --hot)にstartオプションを追加しました。反応ルータはロードする適切なJSXファイルを選択しているので、私はindex.htmlファイルを持っていないことに注意してください。

npm startはパブリックフォルダとファイルを表示しますが、アプリケーションは起動しません。通常、私はindex.htmlファイルをクリックしますが、私は何も持っていません。

私は何が起こっているのか理解できず、解決方法はわかりません。ヘルプは高く評価しました。

package.json:

"scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1", 
    "build": "webpack --config webpack.config.prod.js -p", 
    "start": "webpack-dev-server --inline --hot", 
    "dev": "webpack && node server.js" 
    }, 

webpack.config.js:

module.exports = { 
    entry: './client.js', 
    output: { 
     filename: 'bundle.js', 
     path: __dirname + '/public' 
    }, 
    module: { 
     loaders: [ 
      { 
       test: /\.jsx?$/, 
       exclude: /node_modules/, 
       loader: 'babel-loader', 
       query: { 
        presets: ['react', 'es2015', 'stage-0'] 
       } 
      } 
     ] 
    } 
}; 

server.js

require('babel-register')({ 
    presets: ['react', 'es2015', 'stage-0'] 
}); 

var express = require('express'); 
var config = require('config'); 
var app = express(); 

var serverConfig = config.get('serverConfig'); 

app.use(express.static('public')); 
app.use(require('./routes/index.jsx')); 

app.listen(serverConfig.port, function() { 
    console.log('FactoryWays server running on port ' + serverConfig.port); 
    console.log('Press CTRL-C to stop the server.'); 
}); 

client.js

var ReactDOM = require('react-dom'); 
var React = require('react'); 
var routes = require('./routes/routes.jsx'); 
var Redux = require('redux'); 
var Provider = require('react-redux').Provider; 

function reducer(state) { return state; } 

var store = Redux.createStore(reducer, window.PROPS); 

ReactDOM.render(
    <Provider store={store}> 
     {routes} 
    </Provider>, document 
); 

ルート/ index.jsx:

var router = require('express').Router(); 
var React = require('react'); 
var ReactDOMServer = require('react-dom/server'); 
var ReactRouter = require('react-router'); 
var Redux = require('redux'); 
var Provider = require('react-redux').Provider; 

function reducer(state) { return state; } 

router.get('*', function(request, response) { 
    var initialState = { title: 'Universal React' }; 
    var store = Redux.createStore(reducer, initialState); 

    ReactRouter.match({ 
     routes: require('./routes.jsx'), 
     location: request.url 
    }, function(error, redirectLocation, renderProps) { 
     if (renderProps) { 
      var html = ReactDOMServer.renderToString(
       <Provider store={store}> 
        <ReactRouter.RouterContext {...renderProps} /> 
       </Provider> 
      ); 
      response.send(html); 
     } else { 
      response.status(404).send('Not Found'); 
     } 
    }); 
}); 

module.exports = router; 

ルート/ routes.jsx:

var React = require('react'); 
var ReactRouter = require('react-router'); 
var Router = ReactRouter.Router; 
var Route = ReactRouter.Route; 
var IndexRoute = ReactRouter.IndexRoute; 
var browserHistory = ReactRouter.browserHistory; 

module.exports = (
    <Router history={browserHistory}> 
     <Route path='/' component={require('../views/Layout.jsx')}> 
      <IndexRoute component={require('../views/Index.jsx')} /> 
     </Route> 
    </Router> 
); 

ビュー/ Layout.jsx:

私が反応し、ルータとしてindex.htmlファイルを持っていない10
var React = require('react'); 
var Link = require('react-router').Link; 
var connect = require('react-redux').connect; 

var Layout = React.createClass({ 
    _handleClick: function() { 
     alert(); 
    }, 
    render: function() { 
     var custom = this.props.custom; 
     return (
      <html> 
       <head> 
        <title>{custom.title}</title> 
        <link rel='stylesheet' href='/style.css' /> 
       </head> 
       <body> 
        <h1>{custom.title}</h1> 
        <p>Isn't server-side rendering remarkable?</p> 
        <button onClick={this._handleClick}>Click Me</button> 
        {this.props.children} 
        <ul> 
         <li> 
          <Link to='/'>Home</Link> 
         </li> 
         <li> 
          <Link to='/about'>About</Link> 
         </li> 
        </ul> 
        <script dangerouslySetInnerHTML={{ 
         __html: 'window.PROPS=' + JSON.stringify(custom) 
        }} /> 
        <script src='/bundle.js' /> 
       </body> 
      </html> 
     ); 
    } 
}); 

var wrapper = connect(
    function(state) { 
     return { custom: state }; 
    } 
); 

module.exports = wrapper(Layout); 

答えて

3

通知は、あなたがwebpack-dev-serverを実行している場合は、まだいずれかが必要

ロードするために適切なJSXファイルを選んでいます。

Webpackは、JavaScriptを一緒にバンドルするために使用されます。それでおしまい。あなたの場合(あなたのwebpack.config.jsファイルに基づいて)、あなたのpublicディレクトリにbundle.jsファイルを出力しています。

Webpack Dev Serverは、開発を支援する単純な静的ファイルサーバーです。 server.jsにサーバー構成に関する情報がありません。

パッケージ内の2つのコマンド。

npm start

npm start実行webpack-dev-server:JSONは異なる設定が必要です。デフォルトではwebpack-dev-serverが現在のディレクトリの内容を提供するので、index.htmlをプロジェクトのルートディレクトリに置く必要があります。 index.htmlの内容はシンプルです。ファイルにリンクするscriptタグを含む定型HTMLだけです。

npm dev

はあなたがserver.jsで定義された独自のサーバーを、ローリングしている、しかしnpm devを実行しているとき。その場合、index.html(必要なその他すべての静的ファイル)を生成して配信するように設定されています。

ホットリロードのサーバーを実行する場合は、webpack-dev-middlewareをExpressサーバーに追加できます。

+0

@bejadoさんのポストに感謝します。いくつかの質問:1.私はindex.htmlの内容が 'views/Layout.jsx'の内容と同じであることを理解しています。私はそのコンテンツからindex.htmlファイルを作成し、 'dev'と' start'の両方に提供することができます。私の最終的な目標は私のサーバーを実行し、ホットリロードを行うことです。ですから、webpack-dev-serverをwebpack-dev-middlewareに変更しますか?私はそれを生産と開発の両方でしなければならないのですか?どのようにして両方の条件を設定できますか?可能であれば、両方の条件を詳述してください。 – Mendes

+0

また、webpack-hot-middlewareも見ました。これは何に関連していますか? – Mendes

関連する問題