Tutorial

Cara Mengaktifkan Perenderan Sisi-Server untuk Aplikasi React

React

Pengantar

Perenderan sisi-server atau server-side rendering (SSR) adalah teknik populer untuk merender aplikasi laman tunggal (single page application atau SPA) sisi-klien pada server, lalu mengirim laman yang telah dirender sepenuhnya ke klien. Ini memungkinkan komponen dinamis untuk disajikan sebagai markup HTML statis.

Pendekatan ini dapat berguna untuk optimisasi mesin pencari (SEO) ketika pengindeksan tidak menangani JavaScript dengan benar. Ini juga dapat bermanfaat dalam situasi ketika proses pengunduhan bundel JavaScript besar terganggu oleh jaringan yang lambat.

Dalam tutorial ini, Anda akan menginisialisasi aplikasi React menggunakan Create React App, lalu memodifikasi proyek tersebut untuk mengaktifkan perenderan sisi-server.

Di akhir tutorial ini, Anda akan memiliki proyek yang berjalan dengan aplikasi React sisi-klien dan aplikasi Express sisi-server.

Catatan: Sebagai alternatif, Next.js menawarkan pendekatan modern untuk menciptakan aplikasi statis dan dirender oleh server, yang dibangun dengan React.

Prasyarat

Untuk menyelesaikan tutorial ini, Anda memerlukan:

Tutorial ini diverifikasi dengan Node v14.4.0 dan npm v6.14.5.

Langkah 1 — Menciptakan Aplikasi React dan Memodifikasi Komponen Aplikasi

Pertama-tama, kita menggunakan npx untuk memulai aplikasi React yang baru menggunakan versi terbaru dari Create React App.

Mari kita sebut aplikasi kita my-ssr-app:

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

Kemudian, kita lakukan cd ke direktori baru:

cd my-ssr-app

Terakhir, kita mulai aplikasi sisi-klien baru dalam rangka memverifikasi instalasi tersebut:

  • npm start

Anda akan melihat contoh tampilan aplikasi React di jendela peramban.

Sekarang, mari kita ciptakan komponen <Home>:

  • nano src/Home.js

Selanjutnya, tambahkan kode berikut ke berkas Home.js:

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

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

Ini akan menciptakan tajuk <h1> dengan pesan "Hello" yang ditujukan ke suatu nama.

Selanjutnya, mari kita render <Home> dalam komponen <App>. Buka berkas App.js:

  • nano src/App.js

Kemudian, ganti baris kode yang ada saat ini dengan baris kode baru berikut:

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

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

Ini meneruskan suatu name ke komponen <Home> sehingga pesan yang kita harapkan muncul adalah "Hello Sammy!".

Dalam berkas index.js pada aplikasi, kita akan menggunakan metode hydrate dari ReactDOM alih-alih render untuk mengindikasikan kepada perender DOM bahwa kita merehidrasi kembali aplikasi setelah melakukan render sisi-server.

Mari kita buka berkas index.js:

  • nano index.js

Kemudian, ganti konten dari berkas index.js dengan kode berikut:

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

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

Itu menjadi akhir dari penyiapan sisi-klien, kita dapat melanjutkan ke penyiapan sisi-server.

Langkah 2 — Menciptakan Server Express dan Merender Komponen Aplikasi

Karena kita telah memiliki aplikasi, mari kita siapkan server yang akan mengirimkan versi yang sudah dirender. Kita akan menggunakan Express untuk server kita. Mari kita tambahkan ini ke proyek dengan memasukkan perintah berikut di jendela terminal Anda:

  • npm install express@4.17.1

Atau, gunakan yarn:

  • yarn add express@4.17.1

Selanjutnya, ciptakan direktori server di sebelah direktori src dari aplikasi:

  • mkdir server

Kemudian, ciptakan berkas index.js yang akan berisi kode server Express:

  • nano server/index.js

Tambahkan hasil impor yang akan memerlukan dan mendefinisikan sebagian konstanta:

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

Selanjutnya, tambahkan kode server dengan beberapa penanganan kesalahan:

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

Seperti yang Anda lihat, kita dapat mengimpor komponen <App> pada aplikasi klien secara langsung dari server.

Tiga hal penting berlangsung di sini:

  • Kita memberi tahu Express untuk menyajikan konten dari direktori build sebagai berkas statis.
  • Kita menggunakan metode dari ReactDOMServer, renderToString, untuk merender aplikasi kita ke string HTML statis.
  • Kemudian, kita membaca berkas index.html statis dari aplikasi klien yang sudah dibangun, menyuntikkan konten statis dari aplikasi kita di dalam <div> dengan suatu id dari "root", dan mengirimkannya sebagai respons terhadap permintaan.

Langkah 3 — Mengonfigurasi webpack, Babel, dan Skrip npm

Agar kode server bekerja, kita perlu membundel dan mentranspilasi ini dengan webpack dan Babel. Untuk melakukannya, mari kita tambahkan dependensi dev ke proyek dengan memasukkan perintah berikut di jendela terminal Anda:

  • 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

Atau, gunakan 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

Catatan: Versi sebelumnya dari tutorial ini menginstal babel-core, babel-preset-env, dan babel-preset-react-app. Paket ini sudah lama diarsipkan, sehingga versi repo mono yang digunakan.

Selanjutnya, ciptakan berkas konfigurasi Babel:

  • nano .babelrc.json

Kemudian, tambahkan prasetel env dan react-app:

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

Catatan: Versi sebelumnya dari tutorial ini menggunakan berkas .babelrc (tidak ada ekstensi berkas .json). Ini adalah berkas konfigurasi untuk Babel 6, tetapi ini tidak lagi dapat diterapkan pada Babel 7.

Sekarang, kita akan menciptakan konfigurasi webpack untuk server yang menggunakan Babel Loader untuk mentranspilasi kode. Mulailah dengan menciptakan berkas:

  • nano webpack.server.js

Kemudian, tambahkan konfigurasi berikut ke berkas 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'
      }
    ]
  }
};

Dengan konfigurasi ini, bundel server kita yang telah ditranspilasi akan menjadi keluaran ke folder server-build di dalam berkas bernama index.js.

Perhatikan penggunaan target: 'node' dan externals: [nodeExternals()] dari webpack-node-externals, yang akan mengabaikan berkas dari node_modules di dalam bundel; server dapat mengakses berkas ini secara langsung.

Ini melengkapi instalasi dependensi dan konfigurasi webpack serta Babel.

Sekarang, kita akan meninjau package.json untuk menambahkan skrip npm pembantu:

  • nano package.json

Kita akan menambahkan dev:build-server, dev:start, dan skrip dev ke berkas package.json untuk membangun dan melayani aplikasi SSR kita dengan mudah:

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

Kita menggunakan nodemon untuk memulai ulang server saat kita membuat perubahan padanya. Kita juga menggunakan npm-run-all untuk menjalankan beberapa perintah secara paralel.

Mari kita instal paket itu sekarang dengan memasukkan perintah berikut di jendela terminal Anda:

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

Atau, gunakan yarn:

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

Dengan ini, Anda dapat menjalankan yang berikut ini untuk membangun aplikasi sisi-klien, membundel dan mentranspilasi kode server, dan memulai server pada :3006:

  • npm run dev

Atau, gunakan yarn:

  • yarn run dev

Konfigurasi webpack server kita akan mengawasi perubahan dan server kita akan memulai ulang jika ada perubahan. Namun, untuk aplikasi klien, saat ini kita masih tetap perlu membangunnya setiap kali kita membuat perubahan. Ada masalah yang terbuka untuk hal itu di sini.

Sekarang, buka http://localhost:3006/ di peramban web dan Anda akan melihat aplikasi yang terender sisi-server.

Sebelumnya, kode sumbernya menampilkan:

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

Namun sekarang, dengan perubahan yang Anda buat, kode sumbernya menampilkan:

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

Perenderan sisi-server berhasil mengonversi komponen <App> menjadi HTML.

Kesimpulan

Dalam tutorial ini, Anda telah menginisialisasi aplikasi React dan mengaktifkan perenderan sisi-server.

Dengan tulisan ini, kita telah mempelajari bagian permukaan dari hal-hal yang mungkin dilakukan. Hal-hal cenderung menjadi sedikit lebih rumit setelah perutean, pengambilan data, atau Redux juga perlu menjadi bagian dari aplikasi yang dirender sisi-server.

Salah satu manfaat utama dari menggunakan SSR adalah memiliki aplikasi yang dapat dijelajahi kontennya, bahkan untuk penjelajah yang tidak mengeksekusi kode JavaScript. Ini dapat membantu optimisasi mesin pencari (SEO) dan menyediakan metadata pada saluran media sosial.

SSR juga sering kali dapat membantu performa karena aplikasi yang dimuat secara penuh dikirimkan dari server pada permintaan pertama. Untuk aplikasi nontrivial, jarak tempuh Anda mungkin berbeda karena SSR memerlukan penyiapan yang dapat menjadi sedikit rumit, dan ini menciptakan muatan lebih besar pada server. Perihal menggunakan perenderan sisi-server untuk aplikasi React bergantung pada kebutuhan spesifik Anda dan untung-rugi yang paling masuk akal untuk kasus penggunaan Anda.

Jika Anda ingin mempelajari lebih lanjut tentang React, lihat seri Cara Melakukan Pengodean di React.js dari kami, atau baca halaman topik React kami untuk proyek pemrograman dan latihan.

Creative Commons License