La renderización del lado del servidor (SSR) es una técnica popular para renderizar una aplicación de una sola página (SPA) del lado del cliente en el servidor y enviar una página completamente renderizada al cliente. Esto permite que los componentes dinámicos se presenten como marcado HTML estático.
Este enfoque puede ser útil para la optimización del motor de búsqueda (SEO) cuando la indexación no gestiona el JavaScript correctamente. También puede ser beneficioso en situaciones en las que descargar un paquete JavaScript grande sea difícil debido a una red lenta.
En este tutorial, iniciará una aplicación React usando Create React App y luego modificará el proyecto para habilitar la renderización del lado del servidor.
Al final de este tutorial, tendrá un proyecto funcional con una aplicación React del lado del cliente y una aplicación Express del lado del servidor.
Nota: Alternativamente, Next.js ofrece un enfoque moderno para crear aplicaciones renderizadas estáticas y en servidor creadas con React.
Para completar este tutorial, necesitará lo siguiente:
Este tutorial se verificó con Node v14.4.0 y npm
v6.14.5.
Primero, usamos npx para iniciar una nueva aplicación React usando la última versión de Create React App.
Vamos a invocar nuestra aplicación my-ssr-app:
- npx create-react-app@3.4.1 my-ssr-app
A continuación, hacemos cd
al nuevo directorio:
cd my-ssr-app
Finalmente, iniciamos nuestra nueva aplicación del lado del cliente para verificar la instalación:
- npm start
Debería ver una aplicación React de ejemplo en la ventana de su navegador.
Ahora, vamos a crear un componente <Home>
:
- nano src/Home.js
A continuación, añada el siguiente código al archivo Home.js
:
import React from 'react';
export default props => {
return <h1>Hello {props.name}!</h1>;
};
Esto creará un encabezado <h1>
con un mensaje "Hello"
dirigido a un nombre.
A continuación, vamos a renderizar <Home>
en el componente <App>
. Abra el archivo App.js
:
- nano src/App.js
Luego, sustituya las líneas de código existentes con estas nuevas líneas de código:
import React from 'react';
import Home from './Home';
export default () => {
return <Home name="Sammy" />;
};
Esto pasa un nombre
al componente <Home>
de forma que el mensaje que esperamos mostrar sea "Hello Sammy!"
.
En el archivo index.js
de nuestra aplicación, usaremos el método hydrate
de ReactDOM en vez de render
para indicar al renderizador DOM que estamos rehidratando la aplicación tras una renderización del lado del servidor.
Vamos a abrir el archivo index.js
:
- nano index.js
A continuación, sustituya el contenido del archivo index.js
con el siguiente código:
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.hydrate(<App />, document.getElementById('root'));
Con esto concluye la configuración del lado del cliente y podemos pasar a configurar el lado del servidor.
Ahora que tenemos nuestra aplicación lista, vamos a configurar un servidor que enviará una versión renderizada. Usaremos Express para nuestro servidor. Vamos a añadirlo al proyecto introduciendo el siguiente comando en la ventana de su terminal:
- npm install express@4.17.1
O usando yarn:
- yarn add express@4.17.1
A continuación, cree un directorio server
junto al directorio src
de la aplicación:
- mkdir server
A continuación, cree un nuevo archivo index.js
que contendrá el código del servidor Express:
- nano server/index.js
Añada las importaciones que necesitará y defina algunas constantes:
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();
A continuación, añada el código del servidor con algunas funciones para la gestión de errores:
// ...
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}`);
});
Como puede ver, podemos importar nuestro componente <App>
desde la aplicación del cliente directamente desde el servidor.
Aquí suceden tres cosas importantes:
build
como archivos estáticos.ReactDOMServer
, renderToString
para renderizar nuestra aplicación a una secuencia HTML estática.index.html
desde la aplicación creada del cliente, inyectamos el contenido estático de nuestra aplicación en el <div>
con un id
de "root"
y enviamos eso como la respuesta a la solicitud.npm
Para que funcione el código de nuestro servidor, necesitaremos empaquetarlo y compilarlo usando webpack y Babel. Para conseguir esto, vamos a añadir las dependencias dev al proyecto introduciendo el siguiente comando en la ventana de su terminal:
- 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
O usando 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
Nota: Una versión anterior de este tutorial instaló babel-core
, babel-preset-env
, y babel-preset-react-app
. Estos paquetes han sido archivados desde entonces, y se utilizan las versiones repo mono.
A continuación, cree un archivo de configuración Babel:
- nano .babelrc.json
A continuación, añada los valores prestablecidos env
y react-app
:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
Nota: Una versión anterior de este tutorial usó un archivo .babelrc
(no una extensión de archivo .json
). Este era un archivo de configuración para Babel 6, pero ya no es así para Babel 7.
Ahora, crearemos una configuración webpack para el servidor que utiliza Babel Loader para compilar el código. Comience creando el archivo:
- nano webpack.server.js
Luego, añada las siguientes configuraciones al archivo 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'
}
]
}
};
Con esta configuración, nuestro paquete compilado de servidor aparecerá a la carpeta server-build
en un archivo llamado index.js
.
Observe que el uso target: 'node'
y externals: [nodeExternals()]
desde webpack-node-externals
, que solo omitirá los archivos desde node_modules
en el paquete; el servidor puede acceder a estos archivos directamente.
Esto completa la instalación de la dependencia y la configuración de webpack y Babel.
Ahora repasaremos package.json
para ayudar secuencias de comandos npm
de ayuda:
- nano package.json
Añadiremos secuencias de comandos dev:build-server
, dev:start
y dev
al archivo package.json
para crear y presentar nuestra aplicación SSR fácilmente:
"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:*",
...
},
Usamos nodemon
para reiniciar el servidor cuando realicemos cambios. Y usamos npm-run-all
para ejecutar varios comandos en paralelo.
Vamos a instalar esos paquetes ahora introduciendo los siguientes comandos en la ventana de su terminal:
- npm install nodemon@2.0.4 npm-run-all@4.1.5 --save-dev
O usando yarn:
- yarn add nodemon@2.0.4 npm-run-all@4.1.5 --dev
Con esto, puede ejecutar lo siguiente para crear la aplicación del lado del cliente, empaquetar y compilar el código del servidor e iniciar el servidor en :3006
:
- npm run dev
O usando yarn:
- yarn run dev
La configuración webpack de nuestro servidor vigilará los cambios y nuestro servidor se reiniciará cuando haya cambios. Para la aplicación cliente, sin embargo, actualmente aún debemos crearla cada vez que realicemos cambios. Hay un problema abierto para eso aquí.
Ahora, abra http://localhost:3006/
en su navegador web y verá su aplicación renderizada en el lado del servidor.
Previamente, el código fuente reveló:
Output<div id="root"></div>
Pero ahora, con los cambios que ha realizado, el código fuente revela:
Output<div id="root"><h1 data-reactroot="">Hello <!-- -->Sammy<!-- -->!</h1></div>
La renderización del lado del servidor convirtió el componente <App>
a HTML.
En este tutorial, inició una aplicación React y habilitó la renderización del lado del servidor.
Con esta publicación, solo hemos visto un poco de lo que es posible. Las cosas se complican un poco cuando el direccionamiento, la recuperación de datos o Redux también tengan que ser parte de una aplicación renderizada en el lado del servidor.
Un beneficio importante de usar SR es tener una aplicación que pueda rastrearse para ver su contenido, incluso para rastreadores que no ejecutan código JavaScript. Esto puede ayudar con la optimización de los motores de búsqueda (SEO) y la transmisión de metadatos a los canales de redes sociales.
SSR también puede ayudar a menudo con el rendimiento porque una aplicación completamente cargada se envía desde el servidor sobre la primera solicitud. Para aplicaciones no triviales, su valor puede variar porque SSR requiere una configuración que puede volverse algo complicada y crea una mayor carga sobre el servidor. Si utiliza la renderización del lado del servidor para su aplicación React depende de sus necesidades específicas y de qué ventajas tienen más sentido para su caso de uso.
Si desea aprender más sobre React, eche un vistazo a nuestra serie Cómo crear código en React.js, o consulte nuestra página del tema React para ver ejercicios y proyectos de programación.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!