构建和运行React SSR应用程序作为纯客户端应用程序

问题描述

我的两个应用程序(同一应用程序的CSR和SSR版本)

我已经使用“ create-react-app”创建了一个标准的客户端渲染(CSR)React应用程序。这是仅限客户端的应用程序,整个应用程序都可以在浏览器中部署和运行。

我还创建了此应用程序的服务器端渲染(SSR或通用)版本。构建此应用程序后,它将创建server-bundle.js和client-bundle.js。当应用程序运行时,浏览器从服务器请求该应用程序。服务器返回HTML和对client-bundle.js的引用。该客户端捆绑程序在客户端浏览器中执行,以“水合”现有的HTML内容,或者在客户端导航(服务器未生成内容)的情况下呈现整个内容

此设计有问题

我有两个代码库,其中大多数代码是相同的,包括样式,组件,路线等。如果我需要更改应用程序的一部分,则必须确保在两者中进行相同的更改代码库。

向消费者发布此代码时,我将不得不发布两个应用程序。

我想要的

我想拥有一个可以生成CSR应用程序和SSR应用程序的代码库。

我希望能够扩展我的SSR应用程序中的配置,以便可以创建仅CSR应用程序,例如“ create-react-app”。这样就可以使用以下两种方法之一来构建/运行该应用程序:

  1. 服务器端应用程序-用于在发生客户端导航时使用服务器获取用于捆绑/渲染的客户端包 OR
  2. 客户端应用程序-其中将客户端捆绑包部署到客户端浏览器,并且没有服务器在运行

CSR申请

应用程序结构

public
  index.html
src
  components
     comp1.jsx
     comp2.jsx 
     home.jsx
     page1.jsx
  styles
     styles.css
  index.jsx (contains render method containing the routes)
package.json
etc

src / index.jsx包含

import React from 'react';
import { render } from 'react-dom';
import { browserRouter as Router,Route,Switch } from 'react-router-dom';

import Home from './components/Home';
import Page1 from './components/Page1';

render(
  (
    <Router>
        <Switch>
          <Route exact path="/" component={Home} />
          <Route exact path="/page1" component={Page1} />
        </Switch>
    </Router>
  ),document.getElementById('root'),);

要构建和运行该应用程序,请使用“反应脚本”。我相信“ webpack-dev-server”用于为应用程序提供服务。

"build": "react-scripts build","start": "react-scripts start",

react-scripts更新index.html以添加到客户端捆绑包引用中,并将其移至“ build”目录中。

SSR /通用申请

应用程序结构

public
  index.html
src
  client
     client.jsx (entry point for the client bundle,contains ReactDOM.hydrate)
  components
     comp1.jsx
     comp2.jsx 
  pages
     home.jsx
     page1.jsx
     routes.js
  server
     renderer.jsx (creates the html to return to the client)
     server.js (entry point for the server bundle,an Express server)
  styles
     styles.css
package.json
webpack.base.config.js
webpack.client.config.js (builds the client bundle)
webpack.server.config.js (builds the server bundle)
etc

webpack.client.config.js包含

const path = require('path');
const merge = require('webpack-merge');
const copyPlugin = require('copy-webpack-plugin');
const webpack = require('webpack');
const baseConfig = require('./webpack.base.config.js');

const config = {
  // do not need a 'target' as this is for the browser

  entry: './src/client/client.jsx',output: {
    filename: 'client-bundle.js',path: path.resolve(__dirname,'public'),},plugins: [
    new copyPlugin({
      patterns: [
        {
          from: path.resolve(__dirname,'src','styles'),to: path.resolve(__dirname,],}),new webpack.DefinePlugin({
      'process.env.IS_broWSER': true,};

module.exports = merge(baseConfig,config);

src / client / client.jsx包含

import React from 'react';
import ReactDOM from 'react-dom';
import { browserRouter } from 'react-router-dom';
import { renderRoutes } from 'react-router-config';

import Routes from '../pages/Routes';

ReactDOM.hydrate(
  <browserRouter>
    <div>{renderRoutes(Routes)}</div>
  </browserRouter>,document.querySelector('#root'),);

构建应用捆绑包

"build-server-bundle": "webpack --config webpack.server.config.js","build-client-bundle": "webpack --config webpack.client.config.js",

要运行该应用

node dist/server-bundle.js

SSR应用程序没有“反应脚本”,因为它不是使用“ create-react-app”构建的。

我当时认为应该可以创建一个客户端捆绑包,例如“ create-react-app” create,然后只能在浏览器上运行。

有人知道这是否可行吗?

解决方法

您可以检查以下存储库以获取 SSR 和 CSR。 https://github.com/ashish03399/react-js-ssr-csr-template

此模板提供服务器端渲染和客户端渲染,同时需要最少的第三方模块