Пакетирование посылок и рендеринг на стороне сервера React

Я пытаюсь использовать Parcel Bundler в качестве сборщика моих клиентских файлов, когда использую React Server Side Rendering.

Я использовал Parcel Middleware и назначил ему местоположение точки входа моего клиента.

Когда я запускаю свой скрипт, он показывает, что Parcel связывает мои файлы, но тогда мой метод ReactDOM.hydrate никогда не вызывается, и кажется, что сборщик никогда не использует этот файл.

Вот мой файл server.js:

import Bundler from 'parcel-bundler';
import express from 'express';
import { renderer } from './Helpers';

const app = express();
const bundler = new Bundler(__dirname + '/index.js');

app.use(express.static('public'));
app.use(bundler.middleware());

app.get('*', (req, res) => {
    const context = {};
    const content = renderer(req, context);

    if (context.url) return res.redirect(301, context.url);
    if (context.notFound) res.status(404);

    res.send(content);
});

const listeningPort = 5000;

app.listen(listeningPort, () => {
    console.log(`Server is now live on port ${listeningPort}.`);

и вот мой файл index.js:

import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { routes as Routes } from './Routes';

const routes = Routes;

if (process.env.NODE_ENV === 'development')
    ReactDOM.render(
        <BrowserRouter>
            {routes}
        </BrowserRouter>,
        document.querySelector('#root'));
else
    ReactDOM.hydrate(
        <BrowserRouter>
            {routes}
        </BrowserRouter>,
        document.querySelector('#root'));

и это мой файл рендеринга, который в основном рендерит html-файл:

import React from 'react';
import { renderToString } from 'react-dom/server';
import { StaticRouter } from 'react-router-dom';
import { routes as Routes } from '../Routes';

const routes = Routes;

export default (req, context) => {
  const content = renderToString(
    <StaticRouter location={req.path} context={context}>
      {routes}
    </StaticRouter>
  );

  const lang = "en";

  return `
    <!DOCTYPE html>
    <html lang="${lang}">
      <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="apple-mobile-web-app-capable" content="yes">

        <link href="./public/plugin/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
        <link href="./public/plugin/font-awesome/css/fontawesome-all.min.css" rel="stylesheet" />
        <link href="./public/plugin/et-line/style.css" rel="stylesheet" />
        <link href="./public/plugin/themify-icons/themify-icons.css" rel="stylesheet" />
        <link href="./public/plugin/owl-carousel/css/owl.carousel.min.css" rel="stylesheet" />
        <link href="./public/plugin/magnific/magnific-popup.css" rel="stylesheet" />

        <link href="./public/css/style.css" rel="stylesheet" />
        <link href="./public/css/color/default.css" rel="stylesheet" id="color_theme" />
      </head>
      <body>
        <div id="root">${content}</div>
      </body>
    </html>
  `;
};

Приложение запускается и загружает содержимое в StaticRouter, но никогда не выполняет Hydrate.


person Ali    schedule 04.01.2020    source источник


Ответы (1)


Я наконец исправил свою проблему, используя следующий образец проекта.

https://github.com/reactivestack/parcel-react-ssr

По сути, решение заключалось в том, чтобы не использовать промежуточное программное обеспечение Bundler, а вместо этого объединить клиентскую и серверную стороны отдельно с Parcel и затем запустить проект.

person Ali    schedule 04.01.2020