Thứ ba, 14/07/2020 | 00:00 GMT+7

Cách bật tính năng hiển thị phía server cho ứng dụng React

Kết xuất phía server (SSR) là một kỹ thuật phổ biến để kết xuất một ứng dụng trang đơn phía client (SPA) trên server và sau đó gửi một trang được kết xuất đầy đủ đến client . Điều này cho phép các thành phần động được phục vụ dưới dạng đánh dấu HTML tĩnh.

Cách tiếp cận này có thể hữu ích cho việc tối ưu hóa công cụ tìm kiếm (SEO) khi lập index không xử lý JavaScript đúng cách. Nó cũng có thể có lợi trong các trường hợp download một gói JavaScript lớn bị ảnh hưởng bởi mạng chậm.

Trong hướng dẫn này, bạn sẽ khởi tạo ứng dụng React bằng Tạo ứng dụng React và sau đó sửa đổi dự án để kích hoạt hiển thị phía server .

Ở cuối hướng dẫn này, bạn sẽ có một dự án làm việc với ứng dụng React phía client và ứng dụng Express phía server .

Lưu ý: Ngoài ra, Next.js cung cấp một cách tiếp cận hiện đại để tạo các ứng dụng tĩnh và được kết xuất từ server được xây dựng bằng React.

Yêu cầu

Để hoàn thành hướng dẫn này, bạn cần :

Hướng dẫn này đã được xác minh với Node v14.4.0 và npm v6.14.5.

Bước 1 - Tạo ứng dụng React và sửa đổi thành phần ứng dụng

Đầu tiên, ta sử dụng npx để khởi động một ứng dụng React mới bằng cách sử dụng version Create React App mới nhất.

Hãy gọi ứng dụng của chúng tôi là my-ssr-app :

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

Sau đó, ta cd vào folder mới:

cd my-ssr-app 

Cuối cùng, ta khởi động ứng dụng phía client mới của bạn để xác minh cài đặt:

  • npm start

Bạn sẽ thấy ứng dụng React ví dụ hiển thị trong cửa sổ trình duyệt của bạn .

Bây giờ, hãy tạo một component <Home> :

  • nano src/Home.js

Tiếp theo, thêm mã sau vào file Home.js :

src / Home.js
import React from 'react';  export default props => {   return <h1>Hello {props.name}!</h1>; }; 

Thao tác này sẽ tạo một tiêu đề <h1> với thông báo "Hello" dẫn đến tên.

Tiếp theo, hãy kết xuất <Home> trong thành phần <App> . Mở file App.js :

  • nano src/App.js

Sau đó, thay thế các dòng mã hiện có bằng các dòng mã mới sau:

src / App.js
import React from 'react'; import Home from './Home';  export default () => {   return <Home name="Sammy" />; }; 

Điều này chuyển cùng name cho thành phần <Home> để thông báo mà ta mong đợi hiển thị là "Hello Sammy !" .

Trong index.js của ứng dụng, ta sẽ sử dụng phương pháp hydrate của ReactDOM thay vì render để chỉ ra cho trình kết xuất DOM rằng ta đang bù nước cho ứng dụng sau khi kết xuất phía server .

Hãy mở index.js :

  • nano index.js

Sau đó, thay thế nội dung của index.js bằng mã sau:

index.js
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App';  ReactDOM.hydrate(<App />, document.getElementById('root')); 

Điều đó kết thúc việc cài đặt phía client , ta có thể chuyển sang cài đặt phía server .

Bước 2 - Tạo Server Express và Hiển thị Thành phần Ứng dụng

Bây giờ ta đã có ứng dụng của bạn , hãy cài đặt một server sẽ gửi cùng một version được kết xuất. Ta sẽ sử dụng Express cho server của bạn . Hãy thêm nó vào dự án bằng lệnh lệnh sau vào cửa sổ terminal của bạn:

  • npm install express@4.17.1

Hoặc, sử dụng sợi:

  • yarn add express@4.17.1

Tiếp theo, tạo một folder server bên cạnh folder src của ứng dụng:

  • mkdir server

Sau đó, tạo một index.js mới sẽ chứa mã server Express:

  • nano server/index.js

Thêm các nhập cần và xác định một số hằng số:

server / 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(); 

Tiếp theo, thêm mã server với một số xử lý lỗi:

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

Như bạn thấy , ta có thể nhập thành phần <App> của bạn từ ứng dụng client trực tiếp từ server .

Ba điều quan trọng đang diễn ra ở đây:

  • Ta yêu cầu Express cung cấp nội dung từ folder build dưới dạng file tĩnh.
  • Ta sử dụng một phương thức từ ReactDOMServer , renderToString , để hiển thị ứng dụng của ta thành một chuỗi HTML tĩnh.
  • Sau đó, ta đọc index.html tĩnh từ ứng dụng client đã xây dựng, đưa nội dung tĩnh của ứng dụng vào <div> với id"root" và gửi nó dưới dạng phản hồi cho yêu cầu.

Bước 3 - Cấu hình tập lệnh webpack, Babel và npm

Để mã server của ta hoạt động, ta cần phải đóng gói và chuyển nó, sử dụng webpackBabel . Để thực hiện điều này, hãy thêm các phụ thuộc nhà phát triển vào dự án bằng lệnh lệnh sau vào cửa sổ terminal của bạn:

  • 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

Hoặc, sử dụng sợi:

  • 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

Lưu ý: Phiên bản trước của hướng dẫn này đã cài đặt ứng dụng babel-core , babel-preset-envbabel-preset-react-app . Các gói này đã được lưu trữ và các version mono repo được sử dụng thay thế.

Tiếp theo, tạo file cấu hình Babel:

  • nano .babelrc.json

Sau đó, thêm các cài đặt trước của envreact-app :

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

Lưu ý: Phiên bản trước của hướng dẫn này sử dụng file .babelrc (không có phần mở rộng file .json ). Đây là file cấu hình cho Babel 6, nhưng đây không còn là trường hợp cho Babel 7 nữa.

Bây giờ, ta sẽ tạo một cấu hình webpack cho server sử dụng Babel Loader để truyền mã. Bắt đầu bằng cách tạo file :

  • nano webpack.server.js

Sau đó, thêm các cấu hình sau vào file 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'       }     ]   } }; 

Với cấu hình này, gói server được chuyển đổi của ta sẽ được xuất ra folder server-build trong một file có tên là index.js .

Lưu ý việc sử dụng target: 'node'externals: [nodeExternals()] từ webpack-node-externals , sẽ bỏ qua các file từ node_modules trong gói; server có thể truy cập trực tiếp các file này.

Điều này hoàn tất cài đặt phụ thuộc và cấu hình webpack và Babel.

Bây giờ, ta sẽ truy cập lại package.json để thêm các tập lệnh npm trợ giúp:

  • nano package.json

Ta sẽ thêm tập lệnh dev:build-server , dev:startdev vào file package.json để xây dựng và phục vụ ứng dụng SSR của ta một cách dễ dàng:

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:*",   ... }, 

Ta sử dụng nodemon để khởi động lại server khi ta áp dụng các thay đổi đối với nó. Và ta sử dụng npm-run-all để chạy nhiều lệnh song song.

Hãy cài đặt các gói đó ngay bây giờ bằng lệnh các lệnh sau vào cửa sổ terminal của bạn:

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

Hoặc, sử dụng sợi:

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

Với điều này tại chỗ, bạn có thể chạy phần sau để xây dựng ứng dụng phía client , gói và chuyển mã server , đồng thời khởi động server trên :3006 :

  • npm run dev

Hoặc, sử dụng sợi:

  • yarn run dev

Cấu hình webpack server của ta sẽ theo dõi các thay đổi và server của ta sẽ khởi động lại khi có các thay đổi. Tuy nhiên, đối với ứng dụng client , ta hiện vẫn cần xây dựng ứng dụng này mỗi khi thực hiện thay đổi. Có một vấn đề mở cho điều đó ở đây .

Bây giờ, hãy mở http://localhost:3006/ trong trình duyệt web và bạn sẽ thấy ứng dụng được hiển thị phía server của bạn .

Trước đó, mã nguồn đã tiết lộ:

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

Nhưng bây giờ, với những thay đổi bạn đã thực hiện, mã nguồn tiết lộ:

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

Kết xuất phía server đã chuyển đổi thành công thành phần <App> thành HTML.

Kết luận

Trong hướng dẫn này, bạn đã khởi tạo ứng dụng React và kích hoạt tính năng hiển thị phía server .

Với bài đăng này, ta chỉ sơ bộ về những gì có thể. Mọi thứ có xu hướng trở nên phức tạp hơn một chút khi định tuyến, tìm nạp dữ liệu hoặc Redux cũng cần phải là một phần của ứng dụng được kết xuất phía server .

Một lợi ích chính của việc sử dụng SSR là có một ứng dụng có thể được thu thập thông tin về nội dung của nó, ngay cả đối với các trình thu thập thông tin không thực thi mã JavaScript. Điều này có thể giúp tối ưu hóa công cụ tìm kiếm (SEO) và cung cấp metadata cho các kênh truyền thông xã hội.

SSR thường cũng có thể giúp tăng hiệu suất vì ứng dụng đã tải đầy đủ được gửi xuống từ server trong yêu cầu đầu tiên. Đối với các ứng dụng không tầm thường, quãng đường của bạn có thể thay đổi vì SSR yêu cầu cài đặt có thể hơi phức tạp và nó tạo ra tải trọng lớn hơn trên server . Việc có sử dụng kết xuất phía server cho ứng dụng React của bạn hay không tùy thuộc vào nhu cầu cụ thể của bạn và sự cân bằng nào phù hợp nhất với trường hợp sử dụng của bạn.

Nếu bạn muốn tìm hiểu thêm về React, hãy xem loạt bài Cách viết mã trong React.js của ta hoặc xem trang chủ đề React của ta để biết các bài tập và dự án lập trình.


Tags:

Các tin liên quan

Cách cài đặt và cấu hình Postfix làm server SMTP chỉ gửi trên Ubuntu 18.04
2020-07-06
Cách thiết lập Nền tảng Cloud IDE server mã trên CentOS 7
2020-06-12
Cách thiết lập Nền tảng Cloud IDE server mã trên Debian 10
2020-06-11
Sử dụng Grep & Biểu thức chính quy để tìm kiếm các mẫu văn bản trong Linux
2020-06-05
Cách sử dụng ngôn ngữ AWK để thao tác văn bản trong Linux
2020-05-26
Cách thiết lập Nền tảng Cloud IDE server mã trên Ubuntu 20.04
2020-05-20
Khái niệm cơ bản về việc sử dụng Sed Stream Editor để thao tác văn bản trong Linux
2020-05-19
Sedan trung gian: Thao tác các dòng văn bản trong môi trường Linux
2020-05-19
Cách cài đặt Linux, Nginx, MySQL, PHP ( LEMP) trên Ubuntu 20.04 [Quickstart]
2020-05-14
Cách thiết lập Nền tảng Cloud IDE server mã trên Ubuntu 18.04
2020-05-13