<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 姚观寿</title>
    <description>The latest articles on DEV Community by 姚观寿 (@qq281113270).</description>
    <link>https://dev.to/qq281113270</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F909225%2Fc69b4a97-1b0a-4f4b-9f23-4c0cef8c772a.png</url>
      <title>DEV Community: 姚观寿</title>
      <link>https://dev.to/qq281113270</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/qq281113270"/>
    <language>en</language>
    <item>
      <title>react ssr lazy loading</title>
      <dc:creator>姚观寿</dc:creator>
      <pubDate>Mon, 15 Aug 2022 16:57:32 +0000</pubDate>
      <link>https://dev.to/qq281113270/react-ssr-lazy-loading-3n3e</link>
      <guid>https://dev.to/qq281113270/react-ssr-lazy-loading-3n3e</guid>
      <description>&lt;h1&gt;
  
  
  English document
&lt;/h1&gt;

&lt;h2&gt;
  
  
  An introduction to
&lt;/h2&gt;

&lt;p&gt;Welcome to React-SSR-lazy-Loading documentation!&lt;/p&gt;

&lt;h3&gt;
  
  
  description：
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cost learning, API is almost the same as REACT API &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pages are loaded on access and loaded on demand, cut from code &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Realize the isomorphism of routing, rendering, data and Ajax. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use webpack-dev-middleware and Webpack-hot-server-middleware to realize hot start compiled memory access &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade of SSR + SPA experience. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good scalability. React-ssr-lazy-loading is a project constructed by REACT + Webpack. The required plugins and loaders can be matched according to your needs&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://nextjs.org/docs/getting-started#system-requirements"&gt;System requirements&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/"&gt;Node.js 12.22.0Or higher&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supports MacOS, Windows (including WSL), and Linux&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We recommend creating a new application that will set everything up for you automatically. To create a project, run：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/qq281113270/react-ssr-lazy-loading.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd react-ssr-lazy-loading
npm i
# or
yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the installation is complete ，&lt;/p&gt;

&lt;h4&gt;
  
  
  Install the required dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client Commands
&lt;/h3&gt;

&lt;h4&gt;
  
  
  If you don't need SSR rendering, you can choose start:client:dev
&lt;/h4&gt;

&lt;p&gt;Start development commands that do not require SSR server selection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run   start:client:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Packaging does not require the SSR server's render online packaging command
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  build:client:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSR server render command
&lt;/h3&gt;

&lt;h4&gt;
  
  
  SSR server render development package command  : start:ssr:dev
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run   start:ssr:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  SSR server render line pack command build:ssr:prod
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  build:ssr:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  This command is used to start the SSR server start:server
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  start:server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project directory Structure：
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── README.md     # documentation
├── bin           # Script execution
│   ├── cmd.js    # Script execution
│   └── index.js
├── client      #  Client Directory react code
│   ├── App      
│   │   ├── App.js
│   │   ├── App.less
│   │   ├── CreateApp.js
│   │   └── index.js
│   ├── assets       # Static resource directory
│   │   ├── css
│   │   ├── img
│   │   └── js
│   ├── component   #  Common Component Directory
│   │   ├── Head
│   │   ├── InitState
│   │   ├── LazyLoadingImg
│   │   ├── Loadable
│   │   ├── Loading
│   │   ├── Nav
│   │   └── Table
│   ├── index.js      # Client entry JS
│   ├── pages        #  Route page Page directory
│   │   ├── Home
│   │   ├── User
│   │   └── marketing
│   ├── public         # Webpack introduces an HTML template directory
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   └── logo512.png
│   ├── redux        # react-redux directory
│   │   ├── index.js
│   │   ├── initComponentState.js
│   │   └── models
│   ├── router     #  react   directory
│   │   ├── Routers.js
│   │   ├── addRouterApi.js
│   │   ├── history.js
│   │   ├── historyPush.js
│   │   ├── index.js
│   │   ├── react-router-dom
│   │   ├── routePaths.js
│   │   ├── routesComponent.js
│   │   └── routesConfig.js
│   ├── static    # webpack Do not package static resource directories
│   └── utils        # Some tools and methods
│       ├── CheckDataType.js
│       ├── FloatingBall.js
│       ├── SubscribePublished.js
│       ├── createStore.js
│       ├── ergodic.js
│       ├── getBaseInitState.js
│       ├── getCssAttr.js
│       ├── index.js
│       ├── regular.js
│       ├── resolvePath.js
│       ├── setInitData.js
│       ├── stringToObject.js
│       ├── throttlingStabilization.js
│       └── transformRoutePaths.js
├── dist   # Build Code Package directory
│   ├── client  # Client code Build directory
│   └── server  # Server code Build directory
├── node_modules  #node_modules
├── nodemon.json  # nodemon.json   Restarting the Node Configuration
├── package.json    # npm Depend on the package
├── server       # Code directory of the server
│   ├── app.js   #  Server KOA App
│   ├── controller  # The controller
│   ├── index.js   #   Server entry execution file
│   ├── middleware  # Middleware Addition Directory
│   │   ├── clientRouter
│   │   ├── index.js
│   │   └── webpackHot
│   ├── router   # server Routing directory
│   │   ├── api.js  
│   │   └── index.js
│   ├── service    # service directory
│   │   └── user.js
│   └── utils  # Some tool methods on the server side
│       ├── copyFile.js
│       ├── index.js
│       ├── readFile.js
│       └── watchFile.js
├── webpack  # webpack  The configuration directory
│   ├── config
│   │   ├── client # client webpack configuration
│   │   └── server  # server webpack configuration
│   ├── defineLoader # define Loader
│   │   └── MyExampleWebpackLoader.js
│   ├── definePlugin # define Plugin
│   │   ├── HelloWorldCheckerPlugin
│   │   ├── MyExampleWebpackPlugin.js
│   │   ├── react-loadable
│   │   ├── react-loadable-ssr-addon
│   │   ├── webpack-plugin-copy-file
│   │   ├── webpack-plugin-no-require-css
│   │   ├── webpack-plugin-resolve-alias
│   │   └── webpack-plugin-router
│   ├── index.js   # Webpack Export file
│   └── utils  # Webpack tool method
│       ├── alias.js
│       ├── copyFile.js
│       ├── index.js
│       ├── readFile.js
│       ├── readWriteFiles.js
│       ├── stringToObject.js
│       └── watchFile.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Page configuration and routing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  page
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── client      #  Client Directory code
│   ├── pages  
         ├──Home     #   Home page       
         ├── marketing  #  marketing  Directory Secondary Route
                ├── pages
                      ├── DiscountCoupon   # DiscountCoupon page       
                ├── router      
                       ├── routesConfig.js # Configuring Secondary Routes
│   ├── router      # The routing configuration
        ├── routesConfig.js   # Level-1 Route Configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it is to set the level 1 route, then the configuration file is in client    --&amp;gt; router --&amp;gt; routesConfig.js &lt;/p&gt;

&lt;p&gt;If it's a secondary route then it's in   client    --&amp;gt; pages --&amp;gt; marketing --&amp;gt; router --&amp;gt; routesConfig.js &lt;/p&gt;

&lt;p&gt;routesConfig.js  content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { getHaoKanVideo } from "../assets/js/request/requestApi";
// The routing configuration
export default [
  {
    path: "/",   #  Routing path
    exact: true, # react   Routing parameters exact
    name: "home",  # react routing name
    entry: "/pages/Home/index.js", #   Routing path
    initState: async (parameter = {}) =&amp;gt; {  #  Each page initialization data is used for Node background static request data, or the client has just completed the DOM initialization request data
      const { page = 1, size = 10 } = parameter;
      return await getHaoKanVideo({
        page,
        size
      })
        .then((res) =&amp;gt; {
          const { result: { list = [], total } = {} } = res;
          return {
            list: list.map((item) =&amp;gt; ({
              ...item,
              url: item.userPic
            })),
            total
          };
        })
        .catch(() =&amp;gt; {
          // console.log("Error: ", err.message);
        });
    },
    level: 1 #  Routing Level 1 ROUTING, BECAUSE we render the routing points flat, so the level is identified by this number
  },
  {
    path: "/user",
    name: "user",
    entry: "/pages/User/index.js",
    level: 1
  }
];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we need to add new pages, we can simply add the routesconfig.js parameter to Client Pages after adding the page component.&lt;/p&gt;

&lt;p&gt;Webpack automatically generates the RoutesComponent.js file when it is packaged and compiled.&lt;/p&gt;

&lt;p&gt;React will fetch the routesComponent.js file. Forming a routing address. Support SSR and pure client development mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  router
&lt;/h3&gt;

&lt;p&gt;In React Prop, I inject two routing properties. One is pushRoute. One is routePaths routing component address parameter information.&lt;/p&gt;

&lt;p&gt;We don't need to use this.props. History.push () in React when routing to a jump&lt;/p&gt;

&lt;p&gt;Instead, let's say the name of the home page is home&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   { 
    path: "/",   #  路由路径
    exact: true, # react 路由参数exact
    name: "home",  # react 路由 name
    entry: "/pages/Home/index.js", #  路由路径
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do this using route forwarding&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute('home')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to pass parameters get pass parameters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute({
  name:'home',
  query:{
    age:18,
    name:'yao guan shou'
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jump for the  &lt;a href="http://localhost:3002?age=18&amp;amp;name=yaoGuanShou"&gt;http://localhost:3002?age=18&amp;amp;name=yaoGuanShou&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also pass parameters by address&lt;/p&gt;

&lt;p&gt;Route Path Configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  path: "/:id/:name",    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute({
  name:'home',
  params:{
    age:18,
    name:'yao guan shou'
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jump for the  &lt;a href="http://localhost:3002/18/yaoGuanShou"&gt;http://localhost:3002/18/yaoGuanShou&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Get data  and redux
&lt;/h3&gt;

&lt;h4&gt;
  
  
  node ssr get per-page data
&lt;/h4&gt;

&lt;p&gt;Data acquisition can be rendered into HTML after Node requests data acquisition and sent directly to the client, where the request can be made.&lt;/p&gt;

&lt;p&gt;Configure this if you want to make requests on the Node server. Configured in routesconfig.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; {
    path: "/",
    exact: true,
    name: "home",
    entry: "/pages/Home/index.js",
    initState: async (parameter = {}) =&amp;gt; {  # ajax request
      const { page = 1, size = 10 } = parameter;
      # send ajax request 
      return await getHaoKanVideo({
        page,
        size
      })
        .then((res) =&amp;gt; {
          const { result: { list = [], total } = {} } = res;
          return {
            list: list.map((item) =&amp;gt; ({
              ...item,
              url: item.userPic
            })),
            total
          };
        })
        .catch(() =&amp;gt; {
          // console.log("Error: ", err.message);
        });
    },
    level: 1
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new home.js in redux --&amp;gt; models --&amp;gt; home.js to store the Ajax request data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { setInitData } from "client/utils";
export default (global) =&amp;gt; ({
  state: {
    initState: setInitData(global, "home"),
    count: 0
  },
  reducers: {
    setCount(state, newState) {
      return {
        ...state,
        count: newState
      };
    },

    setInitState(state, newState) {
      return {
        ...state,
        ...newState
      };
    }
  },
  effects: {

  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user requests the page, the node server matches the home route, invokes RoutesConfig.js to request initState to send the Ajax request, and stores the data in redux initState.&lt;/p&gt;

&lt;p&gt;Read the initState data. Import import {mapRedux} from "client/redux"; The mapRedux decorator, which injects Redux into the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { mapRedux } from "client/redux";

const Index = (props) =&amp;gt; {
  let [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const {
    dispatch: { home: { setInitState = () =&amp;gt; {} } = {} } = {},
    state: { home: { initState: { list = [] } = {} } = {} } = {}
  } = props;
  console.log("props=======", props);
  return (
    &amp;lt;div className="home"&amp;gt; home &amp;lt;/div&amp;gt;
  );
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Print the props can see props. State. Home. InitState data.&lt;/p&gt;

&lt;p&gt;The client updates initState. You have setCount and setInitState at props. Dispatch. home. These are the methods defined in redux --&amp;gt; models --&amp;gt; home.js.&lt;/p&gt;

&lt;p&gt;Update initState&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; props.dispatch.home.setInitState(newData) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Node SSR Obtains public data
&lt;/h4&gt;

&lt;p&gt;For example, the client header has a data that every page needs, which we can do in the redux -&amp;gt; models -&amp;gt; baseinitstate.js method defined&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { getWeather } from "../../assets/js/request/requestApi";
const setInitData = (global, name) =&amp;gt; {
  let initState = {};
  if (global &amp;amp;&amp;amp; global.__INITIAL_STATE__ &amp;amp;&amp;amp; global.__INITIAL_STATE__[name]) {
    initState = global.__INITIAL_STATE__[name];
  }

  return initState;
};
export default (global) =&amp;gt; ({
  state: {
    ...setInitData(global, "baseInitState"),
    menuActive: "/"
  },
  reducers: {
    setInitState(state, newState) {
      return {
        ...state,
        ...newState
      };
    },
    setMenuActive(state, newState) {
      return {
        ...state,
        ...newState
      };
    }
  },
  effects: (dispatch) =&amp;gt; ({
    async getWeatherAsync() {
      return await getWeather({
        key: "2d935fc56c5f9ab2ef2165822cedff56",
        city: "440300",
        extensions: "all"
      })
        .then((data) =&amp;gt; {
          dispatch.baseInitState.setInitState({
            weather: data.forecasts[0]
          });
          return data;
        })
        .catch((err) =&amp;gt; {
          console.log("Error: ", err.message);
        });
    }
  })
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Effects defines an Ajax request for getWeatherAsync to get the weather data. GetNameAsync must be defined here&lt;/p&gt;

&lt;p&gt;It starts with get+name+Async and ends with an Async function because in the framework you're going to match regular functions like this, and then you're going to call that method and send the request, and then you're going to store it in redux.&lt;/p&gt;

&lt;h4&gt;
  
  
  client get data
&lt;/h4&gt;

&lt;p&gt;To obtain client data, use the useEffect callback just like the React API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Profile() {
  const [data, setData] = useState(null)
  const [isLoading, setLoading] = useState(false)

  useEffect(() =&amp;gt; {
    setLoading(true)
    fetch('/api/profile-data')
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        setData(data)
        setLoading(false)
      })
  }, [])

  if (isLoading) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;
  if (!data) return &amp;lt;p&amp;gt;No profile data&amp;lt;/p&amp;gt;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{data.name}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{data.bio}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The CSS support
&lt;/h2&gt;

&lt;p&gt;This framework has been configured with CSS and LESS. If you need SASS, you can add SASS Loader in the configuration file of Webpack --&amp;gt; config.&lt;/p&gt;

&lt;h2&gt;
  
  
  The environment variable
&lt;/h2&gt;

&lt;p&gt;.env file public environment variable configuration&lt;/p&gt;

&lt;p&gt;.env.development file development environment variable configuration&lt;/p&gt;

&lt;p&gt;.env.production file configuration of production environment variables&lt;/p&gt;

&lt;p&gt;If you need other environments, you can add the.env.xxxx file and then run the shell script dotenv_config_path=.env.xxxx. Such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"cross-env  target='ssr'  npx babel-node  -r  @babel/register    ./dist/server/index.js   -r  dotenv/config  dotenv_config_path=.env.xxxx ",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  If you feel good move your finger and click starred for me。 thank you
&lt;/h3&gt;

</description>
    </item>
    <item>
      <title>react-ssr-lazy-loading</title>
      <dc:creator>姚观寿</dc:creator>
      <pubDate>Mon, 15 Aug 2022 16:55:20 +0000</pubDate>
      <link>https://dev.to/qq281113270/react-ssr-lazy-loading-122d</link>
      <guid>https://dev.to/qq281113270/react-ssr-lazy-loading-122d</guid>
      <description>&lt;h1&gt;
  
  
  English document
&lt;/h1&gt;

&lt;h2&gt;
  
  
  An introduction to
&lt;/h2&gt;

&lt;p&gt;Welcome to React-SSR-lazy-Loading documentation!&lt;/p&gt;

&lt;h3&gt;
  
  
  description：
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Cost learning, API is almost the same as REACT API &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pages are loaded on access and loaded on demand, cut from code &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Realize the isomorphism of routing, rendering, data and Ajax. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use webpack-dev-middleware and Webpack-hot-server-middleware to realize hot start compiled memory access &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Upgrade of SSR + SPA experience. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Good scalability. React-ssr-lazy-loading is a project constructed by REACT + Webpack. The required plugins and loaders can be matched according to your needs&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://nextjs.org/docs/getting-started#system-requirements"&gt;System requirements&lt;/a&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://nodejs.org/"&gt;Node.js 12.22.0Or higher&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Supports MacOS, Windows (including WSL), and Linux&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We recommend creating a new application that will set everything up for you automatically. To create a project, run：&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/qq281113270/react-ssr-lazy-loading.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd react-ssr-lazy-loading
npm i
# or
yarn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the installation is complete ，&lt;/p&gt;

&lt;h4&gt;
  
  
  Install the required dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Client Commands
&lt;/h3&gt;

&lt;h4&gt;
  
  
  If you don't need SSR rendering, you can choose start:client:dev
&lt;/h4&gt;

&lt;p&gt;Start development commands that do not require SSR server selection&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run   start:client:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Packaging does not require the SSR server's render online packaging command
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  build:client:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSR server render command
&lt;/h3&gt;

&lt;h4&gt;
  
  
  SSR server render development package command  : start:ssr:dev
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run   start:ssr:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  SSR server render line pack command build:ssr:prod
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  build:ssr:prod
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  This command is used to start the SSR server start:server
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm  run  start:server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project directory Structure：
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── README.md     # documentation
├── bin           # Script execution
│   ├── cmd.js    # Script execution
│   └── index.js
├── client      #  Client Directory react code
│   ├── App      
│   │   ├── App.js
│   │   ├── App.less
│   │   ├── CreateApp.js
│   │   └── index.js
│   ├── assets       # Static resource directory
│   │   ├── css
│   │   ├── img
│   │   └── js
│   ├── component   #  Common Component Directory
│   │   ├── Head
│   │   ├── InitState
│   │   ├── LazyLoadingImg
│   │   ├── Loadable
│   │   ├── Loading
│   │   ├── Nav
│   │   └── Table
│   ├── index.js      # Client entry JS
│   ├── pages        #  Route page Page directory
│   │   ├── Home
│   │   ├── User
│   │   └── marketing
│   ├── public         # Webpack introduces an HTML template directory
│   │   ├── favicon.ico
│   │   ├── index.html
│   │   ├── logo192.png
│   │   └── logo512.png
│   ├── redux        # react-redux directory
│   │   ├── index.js
│   │   ├── initComponentState.js
│   │   └── models
│   ├── router     #  react   directory
│   │   ├── Routers.js
│   │   ├── addRouterApi.js
│   │   ├── history.js
│   │   ├── historyPush.js
│   │   ├── index.js
│   │   ├── react-router-dom
│   │   ├── routePaths.js
│   │   ├── routesComponent.js
│   │   └── routesConfig.js
│   ├── static    # webpack Do not package static resource directories
│   └── utils        # Some tools and methods
│       ├── CheckDataType.js
│       ├── FloatingBall.js
│       ├── SubscribePublished.js
│       ├── createStore.js
│       ├── ergodic.js
│       ├── getBaseInitState.js
│       ├── getCssAttr.js
│       ├── index.js
│       ├── regular.js
│       ├── resolvePath.js
│       ├── setInitData.js
│       ├── stringToObject.js
│       ├── throttlingStabilization.js
│       └── transformRoutePaths.js
├── dist   # Build Code Package directory
│   ├── client  # Client code Build directory
│   └── server  # Server code Build directory
├── node_modules  #node_modules
├── nodemon.json  # nodemon.json   Restarting the Node Configuration
├── package.json    # npm Depend on the package
├── server       # Code directory of the server
│   ├── app.js   #  Server KOA App
│   ├── controller  # The controller
│   ├── index.js   #   Server entry execution file
│   ├── middleware  # Middleware Addition Directory
│   │   ├── clientRouter
│   │   ├── index.js
│   │   └── webpackHot
│   ├── router   # server Routing directory
│   │   ├── api.js  
│   │   └── index.js
│   ├── service    # service directory
│   │   └── user.js
│   └── utils  # Some tool methods on the server side
│       ├── copyFile.js
│       ├── index.js
│       ├── readFile.js
│       └── watchFile.js
├── webpack  # webpack  The configuration directory
│   ├── config
│   │   ├── client # client webpack configuration
│   │   └── server  # server webpack configuration
│   ├── defineLoader # define Loader
│   │   └── MyExampleWebpackLoader.js
│   ├── definePlugin # define Plugin
│   │   ├── HelloWorldCheckerPlugin
│   │   ├── MyExampleWebpackPlugin.js
│   │   ├── react-loadable
│   │   ├── react-loadable-ssr-addon
│   │   ├── webpack-plugin-copy-file
│   │   ├── webpack-plugin-no-require-css
│   │   ├── webpack-plugin-resolve-alias
│   │   └── webpack-plugin-router
│   ├── index.js   # Webpack Export file
│   └── utils  # Webpack tool method
│       ├── alias.js
│       ├── copyFile.js
│       ├── index.js
│       ├── readFile.js
│       ├── readWriteFiles.js
│       ├── stringToObject.js
│       └── watchFile.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Page configuration and routing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  page
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── client      #  Client Directory code
│   ├── pages  
         ├──Home     #   Home page       
         ├── marketing  #  marketing  Directory Secondary Route
                ├── pages
                      ├── DiscountCoupon   # DiscountCoupon page       
                ├── router      
                       ├── routesConfig.js # Configuring Secondary Routes
│   ├── router      # The routing configuration
        ├── routesConfig.js   # Level-1 Route Configuration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it is to set the level 1 route, then the configuration file is in client    --&amp;gt; router --&amp;gt; routesConfig.js &lt;/p&gt;

&lt;p&gt;If it's a secondary route then it's in   client    --&amp;gt; pages --&amp;gt; marketing --&amp;gt; router --&amp;gt; routesConfig.js &lt;/p&gt;

&lt;p&gt;routesConfig.js  content&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { getHaoKanVideo } from "../assets/js/request/requestApi";
// The routing configuration
export default [
  {
    path: "/",   #  Routing path
    exact: true, # react   Routing parameters exact
    name: "home",  # react routing name
    entry: "/pages/Home/index.js", #   Routing path
    initState: async (parameter = {}) =&amp;gt; {  #  Each page initialization data is used for Node background static request data, or the client has just completed the DOM initialization request data
      const { page = 1, size = 10 } = parameter;
      return await getHaoKanVideo({
        page,
        size
      })
        .then((res) =&amp;gt; {
          const { result: { list = [], total } = {} } = res;
          return {
            list: list.map((item) =&amp;gt; ({
              ...item,
              url: item.userPic
            })),
            total
          };
        })
        .catch(() =&amp;gt; {
          // console.log("Error: ", err.message);
        });
    },
    level: 1 #  Routing Level 1 ROUTING, BECAUSE we render the routing points flat, so the level is identified by this number
  },
  {
    path: "/user",
    name: "user",
    entry: "/pages/User/index.js",
    level: 1
  }
];

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we need to add new pages, we can simply add the routesconfig.js parameter to Client Pages after adding the page component.&lt;/p&gt;

&lt;p&gt;Webpack automatically generates the RoutesComponent.js file when it is packaged and compiled.&lt;/p&gt;

&lt;p&gt;React will fetch the routesComponent.js file. Forming a routing address. Support SSR and pure client development mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  router
&lt;/h3&gt;

&lt;p&gt;In React Prop, I inject two routing properties. One is pushRoute. One is routePaths routing component address parameter information.&lt;/p&gt;

&lt;p&gt;We don't need to use this.props. History.push () in React when routing to a jump&lt;/p&gt;

&lt;p&gt;Instead, let's say the name of the home page is home&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   { 
    path: "/",   #  路由路径
    exact: true, # react 路由参数exact
    name: "home",  # react 路由 name
    entry: "/pages/Home/index.js", #  路由路径
    }

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can do this using route forwarding&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute('home')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you need to pass parameters get pass parameters&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute({
  name:'home',
  query:{
    age:18,
    name:'yao guan shou'
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jump for the  &lt;a href="http://localhost:3002?age=18&amp;amp;name=yaoGuanShou"&gt;http://localhost:3002?age=18&amp;amp;name=yaoGuanShou&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also pass parameters by address&lt;/p&gt;

&lt;p&gt;Route Path Configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  path: "/:id/:name",    
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;this.pushRoute({
  name:'home',
  params:{
    age:18,
    name:'yao guan shou'
  }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Jump for the  &lt;a href="http://localhost:3002/18/yaoGuanShou"&gt;http://localhost:3002/18/yaoGuanShou&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Get Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Get data  and redux
&lt;/h3&gt;

&lt;h4&gt;
  
  
  node ssr get per-page data
&lt;/h4&gt;

&lt;p&gt;Data acquisition can be rendered into HTML after Node requests data acquisition and sent directly to the client, where the request can be made.&lt;/p&gt;

&lt;p&gt;Configure this if you want to make requests on the Node server. Configured in routesconfig.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; {
    path: "/",
    exact: true,
    name: "home",
    entry: "/pages/Home/index.js",
    initState: async (parameter = {}) =&amp;gt; {  # ajax request
      const { page = 1, size = 10 } = parameter;
      # send ajax request 
      return await getHaoKanVideo({
        page,
        size
      })
        .then((res) =&amp;gt; {
          const { result: { list = [], total } = {} } = res;
          return {
            list: list.map((item) =&amp;gt; ({
              ...item,
              url: item.userPic
            })),
            total
          };
        })
        .catch(() =&amp;gt; {
          // console.log("Error: ", err.message);
        });
    },
    level: 1
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new home.js in redux --&amp;gt; models --&amp;gt; home.js to store the Ajax request data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { setInitData } from "client/utils";
export default (global) =&amp;gt; ({
  state: {
    initState: setInitData(global, "home"),
    count: 0
  },
  reducers: {
    setCount(state, newState) {
      return {
        ...state,
        count: newState
      };
    },

    setInitState(state, newState) {
      return {
        ...state,
        ...newState
      };
    }
  },
  effects: {

  }
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the user requests the page, the node server matches the home route, invokes RoutesConfig.js to request initState to send the Ajax request, and stores the data in redux initState.&lt;/p&gt;

&lt;p&gt;Read the initState data. Import import {mapRedux} from "client/redux"; The mapRedux decorator, which injects Redux into the component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { mapRedux } from "client/redux";

const Index = (props) =&amp;gt; {
  let [page, setPage] = useState(1);
  const [loading, setLoading] = useState(false);
  const {
    dispatch: { home: { setInitState = () =&amp;gt; {} } = {} } = {},
    state: { home: { initState: { list = [] } = {} } = {} } = {}
  } = props;
  console.log("props=======", props);
  return (
    &amp;lt;div className="home"&amp;gt; home &amp;lt;/div&amp;gt;
  );
};


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Print the props can see props. State. Home. InitState data.&lt;/p&gt;

&lt;p&gt;The client updates initState. You have setCount and setInitState at props. Dispatch. home. These are the methods defined in redux --&amp;gt; models --&amp;gt; home.js.&lt;/p&gt;

&lt;p&gt;Update initState&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; props.dispatch.home.setInitState(newData) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Node SSR Obtains public data
&lt;/h4&gt;

&lt;p&gt;For example, the client header has a data that every page needs, which we can do in the redux -&amp;gt; models -&amp;gt; baseinitstate.js method defined&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { getWeather } from "../../assets/js/request/requestApi";
const setInitData = (global, name) =&amp;gt; {
  let initState = {};
  if (global &amp;amp;&amp;amp; global.__INITIAL_STATE__ &amp;amp;&amp;amp; global.__INITIAL_STATE__[name]) {
    initState = global.__INITIAL_STATE__[name];
  }

  return initState;
};
export default (global) =&amp;gt; ({
  state: {
    ...setInitData(global, "baseInitState"),
    menuActive: "/"
  },
  reducers: {
    setInitState(state, newState) {
      return {
        ...state,
        ...newState
      };
    },
    setMenuActive(state, newState) {
      return {
        ...state,
        ...newState
      };
    }
  },
  effects: (dispatch) =&amp;gt; ({
    async getWeatherAsync() {
      return await getWeather({
        key: "2d935fc56c5f9ab2ef2165822cedff56",
        city: "440300",
        extensions: "all"
      })
        .then((data) =&amp;gt; {
          dispatch.baseInitState.setInitState({
            weather: data.forecasts[0]
          });
          return data;
        })
        .catch((err) =&amp;gt; {
          console.log("Error: ", err.message);
        });
    }
  })
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Effects defines an Ajax request for getWeatherAsync to get the weather data. GetNameAsync must be defined here&lt;/p&gt;

&lt;p&gt;It starts with get+name+Async and ends with an Async function because in the framework you're going to match regular functions like this, and then you're going to call that method and send the request, and then you're going to store it in redux.&lt;/p&gt;

&lt;h4&gt;
  
  
  client get data
&lt;/h4&gt;

&lt;p&gt;To obtain client data, use the useEffect callback just like the React API&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function Profile() {
  const [data, setData] = useState(null)
  const [isLoading, setLoading] = useState(false)

  useEffect(() =&amp;gt; {
    setLoading(true)
    fetch('/api/profile-data')
      .then((res) =&amp;gt; res.json())
      .then((data) =&amp;gt; {
        setData(data)
        setLoading(false)
      })
  }, [])

  if (isLoading) return &amp;lt;p&amp;gt;Loading...&amp;lt;/p&amp;gt;
  if (!data) return &amp;lt;p&amp;gt;No profile data&amp;lt;/p&amp;gt;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{data.name}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{data.bio}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The CSS support
&lt;/h2&gt;

&lt;p&gt;This framework has been configured with CSS and LESS. If you need SASS, you can add SASS Loader in the configuration file of Webpack --&amp;gt; config.&lt;/p&gt;

&lt;h2&gt;
  
  
  The environment variable
&lt;/h2&gt;

&lt;p&gt;.env file public environment variable configuration&lt;/p&gt;

&lt;p&gt;.env.development file development environment variable configuration&lt;/p&gt;

&lt;p&gt;.env.production file configuration of production environment variables&lt;/p&gt;

&lt;p&gt;If you need other environments, you can add the.env.xxxx file and then run the shell script dotenv_config_path=.env.xxxx. Such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"cross-env  target='ssr'  npx babel-node  -r  @babel/register    ./dist/server/index.js   -r  dotenv/config  dotenv_config_path=.env.xxxx ",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  If you feel good move your finger and click starred for me。 thank you
&lt;/h3&gt;

</description>
      <category>redishackathon</category>
    </item>
  </channel>
</rss>
