简体   繁体   中英

Parcel Bundler & React Server Side Rendering

I am trying to use Parcel Bundler as the bundler of my client files when I use React Server Side Rendering.

I have used the Parcel Middleware and assigned it with the location of my client entry point.

When I start my script, it shows that Parcel is bundling my files but then my ReactDOM.hydrate method is never called and it seems that the bundler never uses that file at all.

Here is my server.js file:

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}.`);

and here is my index.js file:

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'));

and this is my renderer file which basically renders the html file:

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>
  `;
};

The application runs and loads the content inside the StaticRouter but never does the Hydrate.

I finally fixed my issue using the following sample project.

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

Basically the solution was to not using the Bundler Middleware but instead bundling the client-side and server-side separately with Parcel and then running the project.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM