1

react と create-react-app を使用してサーバー側のレンダリングを有効にしたかっただけです。

シンプルな反応コンポーネントを文字列として返す server/index.js ファイルを作成しました。

//require('import-export');
//require('babel-register')({ ignore: /\/(build|node_modules)\//, presets: ['react-app', 'es2015', 'react'] });
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const fs = require('fs');
const index = require('./index.js');
const react = require('react');
const reactServerDom = require('react-dom/server');
const renderToString = reactServerDom.renderToString;
const ourComponent = require('../src/App.js');
const app = express();

// Setup logger
app.use(morgan(':remote-addr - :remote-user [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] :response-time ms'));

// Serve static assets - NEEDS TO BE ACTIVATED LATER WHEN RENDERTOSTRING WORKS!
//app.use(express.static(path.resolve(__dirname, '..', 'build')));

app.get('/', (req, res) => {
  const filePath = path.resolve(__dirname, '..', 'build', 'index.html');
  let result = '';
  fs.readFile(filePath, 'utf8', function (err, data) {
    if (err) {
      return console.log(err);
    }
    const ReactApp = renderToString(react.createElement(ourComponent));
    result = data.replace('{{SSR}}', ReactApp);
    res.send(result);
  });
});

const port = 9007;

app.listen(port, () => {
  console.log(`App listening on port ${ port }`);
});

module.exports = app;

レンダリングする必要があるコンポーネントは、create-react-app から誰もが取得する単なるサンプル コンポーネントです。

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

package.json 内には、コマンドyarn serverまたはnpm run serverを使用して、babel-node でサーバーを起動する次のコマンドがあります。

...
  "scripts": {
    "start": "react-scripts start",
    "server": "NODE_ENV=development babel-node --presets=es2015,react server/index.js",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
...

しかし、私はまだ次のエラーが発生します:

$ NODE_ENV=development babel-node --presets=es2015,react server/index.js
/home/sonnenfeld/ssr-render/src/logo.svg:4
React.createElement(
^

ReferenceError: React is not defined

コンポーネントから svg を削除すると、別のエラーが発生します。

SyntaxError: /home/sonnenfeld/ssr-render/src/App.css: Unexpected token (1:0)
> 1 | .App {
    | ^
  2 |   text-align: center;
  3 | }
  4 |

私はすでにbabel-registerでbabelフックを試しましたが、成功しませんでした。

create-react-app をエクスプレスで使用する場合、server.js とすべての依存関係をバニラ JavaScript にトランスパイルするための良いアプローチは何でしょうか?

4

1 に答える 1

0

サーバー側のレンダリングは非常に難しい場合があります。そこで、完全に next-js に切り替えました。

スタイル付きコンポーネントの問題は、公式の回避策で解決されましたhttps://www.styled-components.com/docs/advanced#server-side-rendering

于 2017-06-14T16:11:28.590 に答える