react 服务器端渲染_如何为React App启用服务器端渲染

react 服务器端渲染

介绍 (Introduction)

Server-side rendering (SSR) is a popular technique for rendering a client-side single page application (SPA) on the server and then sending a fully rendered page to the client. This allows for dynamic components to be served as static HTML markup.

服务器端呈现 (SSR)是一种流行的技术,用于在服务器上呈现客户端单页应用程序 (SPA),然后将完整呈现的页面发送给客户端。 这允许将动态组件用作静态HTML标记。

This approach can be useful for search engine optimization (SEO) when indexing does not handle JavaScript properly. It may also be beneficial in situations where downloading a large JavaScript bundle is impaired by a slow network.

当索引无法正确处理JavaScript时,此方法对于搜索引擎优化(SEO)很有用。 在网络速度较慢而无法下载大型JavaScript包的情况下,这也可能是有益的。

In this tutorial, you will initialize a React app using Create React App and then modify the project to enable server-side rendering.

在本教程中,您将使用创建React App初始化React应用 ,然后修改项目以启用服务器端渲染。

At the end of this tutorial, you will have a working project with a client-side React application and a server-side Express application.

在本教程的最后,您将拥有一个包含客户端React应用程序和服务器Express应用程序的工作项目。

Note: Alternatively, Next.js offers a modern approach to creating static and server-rendered applications built with React.

注意:另外, Next.js提供了一种现代方法来创建使用React构建的静态和服务器渲染应用程序。

先决条件 (Prerequisites)

To complete this tutorial, you will need:

要完成本教程,您将需要:

This tutorial was verified with Node v14.4.0 and npm v6.14.5.

本教程已通过Node v14.4.0和npm v6.14.5进行了验证。

第1步—创建React App和修改App组件 (Step 1 — Creating the React App and Modifying the App Component)

First, we use npx to start up a new React app using the latest version of Create React App.

首先,我们使用npx使用最新版本的Create React App来启动新的React应用程序。

Let’s call our app my-ssr-app:

让我们将我们的应用称为my-ssr-app :

  • npx create-react-app@3.4.1 my-ssr-app

    npx create-react-app@3.4.1 my-ssr-app

Then, we cd into the new directory:

然后,我们cd到新目录:

cd my-ssr-app

Finally, we start our new client-side app in order to verify the installation:

最后,我们启动新的客户端应用程序以验证安装:

  • npm start

    npm开始

You should see an example React app display in your browser window.

您应该在浏览器窗口中看到一个示例React应用程序显示。

Now, let’s create a <Home> component:

现在,让我们创建一个<Home>组件:

  • nano src/Home.js

    纳米src / Home.js

Next, add the following code to the Home.js file:

接下来,将以下代码添加到Home.js文件中:

src/Home.js
src / Home.js
import React from 'react';

export default props => {
  return <h1>Hello {props.name}!</h1>;
};

This will create a <h1> heading with a "Hello" message directed to a name.

这将创建一个<h1>标题,其中包含指向名称的"Hello"消息。

Next, let’s render the <Home> in the <App> component. Open the App.js file:

接下来,让我们在<App>组件中呈现<Home> 。 打开App.js文件:

  • nano src/App.js

    纳米src / App.js

Then, replace the existing lines of code with these new lines of code:

然后,用以下新代码行替换现有代码行:

src/App.js
src / App.js
import React from 'react';
import Home from './Home';

export default () => {
  return <Home name="Sammy" />;
};

This passes along a name to <Home> component so the message that we expect to display is "Hello Sammy!".

这将name传递给<Home>组件,因此我们希望显示的消息是"Hello Sammy !"

In our app’s index.js file, we’ll use ReactDOM’s hydrate method instead of render to indicate to the DOM renderer that we’re rehydrating the app after a server-side render.

在我们的应用程序的index.js文件,我们将使用ReactDOM的hydrate的方法 ,而不是render ,以指示DOM渲染器,我们正在复水后,服务器端渲染应用程序。

Let’s open the index.js file:

让我们打开index.js文件:

  • nano index.js

    纳米index.js

Then, replace the contents of the index.js file with the following code:

然后,用以下代码替换index.js文件的内容:

index.js
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.hydrate(<App />, document.getElementById('root'));

That concludes setting up the client-side, we can move on to setting up the server-side.

设置客户端到此结束,我们可以继续设置服务器端了。

第2步-创建Express Server并呈现App组件 (Step 2 — Creating an Express Server and Rendering the App Component)

Now that we have our app in place, let’s set up a server that will send along a rendered version. We’ll use Express for our server. Let’s add it to the project by entering the following command in your terminal window:

现在我们有了应用程序,让我们设置一个服务器,该服务器将发送渲染版本。 我们将对服务器使用Express 。 通过在终端窗口中输入以下命令,将其添加到项目中:

  • npm install express@4.17.1

    NPM安装快递@ 4.17.1

Or, using yarn:

或者,使用纱线:

  • yarn add express@4.17.1

    纱加快递@ 4.17.1

Next, create a server directory next to the app’s src directory:

接下来,在应用程序的src目录旁边创建一个server目录:

  • mkdir server

    mkdir服务器

Then, create a new index.js file that will contain the Express server code:

然后,创建一个新的index.js文件,其中将包含Express服务器代码:

  • nano server/index.js

    纳米服务器/ index.js

Add the imports that will need and define some constants:

添加将需要的导入并定义一些常量:

server/index.js
服务器/ index.js
import path from 'path';
import fs from 'fs';

import React from 'react';
import express from 'express';
import ReactDOMServer from 'react-dom/server';

import App from '../src/App';

const PORT = process.env.PORT || 3006;
const app = express();

Next, add the server code with some error handling:

接下来,添加带有一些错误处理的服务器代码:

server/index.js
服务器/ index.js
// ...

app.get('/', (req, res) => {
  const app = ReactDOMServer.renderToString(<App />);

  const indexFile = path.resolve('./build/index.html');
  fs.readFile(indexFile, 'utf8', (err, data) => {
    if (err) {
      console.error('Something went wrong:', err);
      return res.status(500).send('Oops, better luck next time!');
    }

    return res.send(
      data.replace('<div id="root"></div>', `<div id="root">${app}</div>`)
    );
  });
});

app.use(express.static('./build'));

app.listen(PORT, () => {
  console.log(`Server is listening on port ${PORT}`);
});

As you may see, we can import our <App> component from the client app directly from the server.

如您所见,我们可以直接从服务器从客户端应用程序导入<App>组件。

Three important things are taking place here:

这里发生了三件重要的事情:

  • We tell Express to serve contents from the build directory as static files.

    我们告诉Express将build目录中的内容作为静态文件提供。

  • We use a method from ReactDOMServer, renderToString, to render our app to a static HTML string.

    我们使用的方法ReactDOMServerrenderToString ,我们的应用中呈现静态HTML字符串。

  • We then read the static index.html file from the built client app, inject our app’s static content in the <div> with an id of "root", and send that as the response to the request.

    然后,我们从内置的客户端应用程序中读取静态index.html文件,将我们应用程序的静态内容注入id"root"<div> ,并将其作为对请求的响应进行发送。

第3步-配置webpack,Babel和npm脚本 (Step 3 — Configuring webpack, Babel, and npm Scripts)

For our server code to work, we’ll need to bundle and transpile it, using webpack and Babel. To accomplish this, let’s add the dev dependencies to the project by entering the following command in your terminal window:

为了使我们的服务器代码正常工作,我们需要使用webpackBabel对其进行捆绑和翻译。 为此,通过在终端窗口中输入以下命令,将dev依赖项添加到项目中:

  • npm install webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --save-dev

    npm安装webpack @ 4.42.0 webpack-cli @ 3.3.12 webpack-node-externals @ 1.7.2 @ babel / core @ 7.10.4 babel-loader @ 8.1.0 @ babel / preset-env @ 7.10.4 @babel /预设React@ 7.10.4 --save-dev

Or, using yarn:

或者,使用纱线:

  • yarn add webpack@4.42.0 webpack-cli@3.3.12 webpack-node-externals@1.7.2 @babel/core@7.10.4 babel-loader@8.1.0 @babel/preset-env@7.10.4 @babel/preset-react@7.10.4 --dev

    纱线添加webpack @ 4.42.0 webpack-cli @ 3.3.12 webpack-node-externals @ 1.7.2 @ babel / core @ 7.10.4 babel-loader @ 8.1.0 @ babel / preset-env @ 7.10.4 @babel /预设React@ 7.10.4 --dev

Note: An earlier version of this tutorial installed babel-core, babel-preset-env, and babel-preset-react-app. These packages have since been archived, and the mono repo versions are utilized instead.

注意:本教程的早期版本安装了babel-corebabel-preset-envbabel-preset-react-app 。 此后,这些软件包已被归档,而改为使用mono repo版本。

Next, create a Babel configuration file:

接下来,创建一个Babel配置文件:

  • nano .babelrc.json

    纳米.babelrc.json

Then, add the env and react-app presets:

然后,添加envreact-app预设:

.babelrc.json
.babelrc.json
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react"
  ]
}

Note: An earlier version of this tutorial used a .babelrc file (no .json file extension). This was a configuration file for Babel 6, but this is no longer the case for Babel 7.

注:本教程的早期版本使用的.babelrc文件(不.json文件扩展名)。 这是Babel 6的配置文件,但Babel 7不再是这种情况。

Now, we will create a webpack config for the server that uses Babel Loader to transpile the code. Start by creating the file:

现在,我们将为使用Babel Loader转换代码的服务器创建一个webpack配置。 首先创建文件:

  • nano webpack.server.js

    纳米webpack.server.js

Then, add the following configurations to the webpack.server.js file:

然后,将以下配置添加到webpack.server.js文件:

webpack.server.js
webpack.server.js
const path = require('path');
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: './server/index.js',

  target: 'node',

  externals: [nodeExternals()],

  output: {
    path: path.resolve('server-build'),
    filename: 'index.js'
  },

  module: {
    rules: [
      {
        test: /\.js$/,
        use: 'babel-loader'
      }
    ]
  }
};

With this configuration, our transpiled server bundle will be output to the server-build folder in a file called index.js.

使用此配置,我们的已编译服务器捆绑将输出到名为index.js的文件的server-build文件夹中。

Note the use of target: 'node' and externals: [nodeExternals()] from webpack-node-externals, which will omit the files from node_modules in the bundle; the server can access these files directly.

请注意webpack-node-externalstarget: 'node'externals: [nodeExternals()] webpack-node-externals ,这将忽略包中node_modules中的文件; 服务器可以直接访问这些文件。

This completes the dependency installation and webpack and Babel configuration.

这样就完成了依赖项安装以及webpack和Babel的配置。

Now, we will revisit package.json to add helper npm scripts:

现在,我们将重新访问package.json以添加辅助npm脚本:

  • nano package.json

    纳米package.json

We will add dev:build-server, dev:start, and dev scripts to the package.json file to build and serve our SSR application easily:

我们将在package.json文件中添加dev:build-serverdev:startdev脚本,以轻松构建和提供SSR应用程序:

package.json
package.json
"scripts": {
  "dev:build-server": "NODE_ENV=development webpack --config webpack.server.js --mode=development -w",
  "dev:start": "nodemon ./server-build/index.js",
  "dev": "npm-run-all --parallel build dev:*",
  ...
},

We use nodemon to restart the server when we make changes to it. And we use npm-run-all to run multiple commands in parallel.

更改服务器后,我们使用nodemon重新启动服务器。 我们使用npm-run-all并行运行多个命令。

Let’s install those packages now by entering the following commands in your terminal window:

现在,通过在终端窗口中输入以下命令来安装这些软件包:

  • npm install nodemon@2.0.4 npm-run-all@4.1.5 --save-dev

    npm安装nodemon @ 2.0.4 npm-run-all @ 4.1.5 --save-dev

Or, using yarn:

或者,使用纱线:

  • yarn add nodemon@2.0.4 npm-run-all@4.1.5 --dev

    纱线添加nodemon @ 2.0.4 npm-run-all @ 4.1.5 --dev

With this in place, you can run the following to build the client-side app, bundle and transpile the server code, and start up the server on :3006:

有了这个,您可以运行以下命令来构建客户端应用程序,捆绑并转译服务器代码,并在:3006上启动服务器:

  • npm run dev

    npm run dev

Or, using yarn:

或者,使用纱线:

  • yarn run dev

    纱线运行开发

Our server webpack config will watch for changes and our server will restart on changes. For the client app, however, we currently still need to build it each time we make changes. There’s an open issue for that here.

我们的服务器webpack配置将监视更改,我们的服务器将在更改后重新启动。 但是,对于客户端应用程序,我们每次更改时仍需要构建它。 这里有一个未解决的问题

Now, open http://localhost:3006/ in your web browser and you will see your server-side rendered app.

现在,在Web浏览器中打开http://localhost:3006/ ,您将看到服务器端渲染的应用程序。

Previously, the source code revealed:

以前,源代码显示:


   
   
Output
<div id="root"></div>

But now, with the changes you made, the source code reveals:

但是现在,随着您所做的更改,源代码揭示了:


   
   
Output
<div id="root"><h1 data-reactroot="">Hello <!-- -->Sammy<!-- -->!</h1></div>

The server-side rendering successfully converted the <App> component into HTML.

服务器端渲染已成功将<App>组件转换为HTML。

结论 (Conclusion)

In this tutorial, you initialized a React application and enabled server-side rendering.

在本教程中,您初始化了React应用程序并启用了服务器端渲染。

With this post, we just scratched the surface at what’s possible. Things tend to get a bit more complicated once routing, data fetching, or Redux also need to be part of a server-side rendered app.

在这篇文章中,我们只是在可能的情况下进行了初步研究。 一旦路由,数据获取或Redux也需要成为服务器端渲染应用程序的一部分,事情就会变得更加复杂。

One major benefit of using SSR is having an app that can be crawled for its content, even for crawlers that don’t execute JavaScript code. This can help with search engine optimization (SEO) and providing metadata to social media channels.

使用SSR的一个主要好处是拥有一个可以对其内容进行爬网的应用程序,即使是不执行JavaScript代码的爬网程序。 这有助于搜索引擎优化(SEO)并向社交媒体渠道提供元数据。

SSR can also often help with performance because a fully loaded app is sent down from the server on the first request. For non-trivial apps, your mileage may vary because SSR requires a setup that can get a bit complicated, and it creates a bigger load on the server. Whether to use server-side rendering for your React app depends on your specific needs and on which trade-offs make the most sense for your use case.

SSR通常还可以帮助提高性能,因为在第一次请求时,就会从服务器向下发送完全加载的应用程序。 对于非平凡的应用程序,您的里程可能会有所不同,因为SSR要求的设置可能会有些复杂,并且会给服务器带来更大的负载。 是否为您的React应用程序使用服务器端渲染取决于您的特定需求以及哪种权衡最适合您的用例。

If you’d like to learn more about React, take a look at our How To Code in React.js series, or check out our React topic page for exercises and programming projects.

如果您想了解有关React的更多信息,请查看我们的React.js系列中的How To Code ,或查看我们的React主题页面以获取练习和编程项目。

翻译自: https://www.digitalocean.com/community/tutorials/react-server-side-rendering

react 服务器端渲染

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值