Как сделать серверный рендеринг на React?

Задался вопросом сделать серверный рендеринг для приложения на реакте. Нашел примеры, все получилось. Но как быть с собранным приложением в один файл? У меня, получается, сервер отдает статичные 3 файла: bundle.js, bundle.js.map и index.html.
Буду благодарен за советы.
  • Вопрос задан
  • 5334 просмотра
Решения вопроса 1
alexfedoseev
@alexfedoseev
React & Rails Dev
index.html — его быть не должно.

Должен быть шаблон (jade, handlebars, whatever), в который:
  • через переменную вставляется DOM от реакта (результат React.renderToString);
  • после него через тег script подключается файл приложения (bundle.js)


Сервер рендерит этот шаблон и отдает html с клиентским приложением на клиента.

bundle.js.map — это SourceMaps, их в production быть не должно, оно убирается через настройку Webpack.

Роутинг

Если это SPA:

import express    from 'express';
import React      from 'react';
import Router     from 'react-router';
import Location   from 'react-router/lib/Location';

import App        from '/path/to/App';
import routes     from '/path/to/routes';


const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.use('/', middleware);

function middleware(req, res, next) {
  
  const location = new Location(req.path, req.query);
  
  Router.run(routes, location, (error, initialState, transition) => {
    
    const body   = React.renderToString(<App {...initialState} />);
    const layout = `${process.cwd()}/path/to/layout.jade`;
    const html   = Jade.compileFile(layout, { pretty: false })({ body });
    
    res.send(html);
    
  });
  
}


Если это статика:

import express  from 'express';
import React    from 'react';

import Main     from 'components/Main';
import About    from 'components/About';


const app = express();

app.use(express.static(path.join(__dirname, 'public')));

app.get('/', (req, res) => middleware(req, res, Main));
app.get('/about', (req, res) => middleware(req, res, About));

function middleware(req, res, Component) {
  
  const body   = React.renderToString(<Component />);
  const layout = `${process.cwd()}/path/to/layout.jade`;
  const html   = Jade.compileFile(layout, { pretty: false })({ body });
  
  res.send(html);

}


/* Jade Layout */

doctype html
html
  
  head
    // head stuff...

  body
    #app!= body
    script(src="/bundle.js")
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы