10. Ejemplo [nuxt-07]: los contextos de cliente y servidor
10.1. Présentation
El ejemplo [nuxt-07] tiene como objetivo explorar el objeto [context] tanto del lado del servidor como del lado del cliente. No hay que olvidar que estos dos actores de las aplicaciones [nuxt] están separados: no comparten nada, salvo:
- lo que el servidor decide enviar al cliente (en la respuesta HTTP y la página enviada);
- lo que el cliente decide enviar al servidor (en su solicitud HTTP);
Por lo tanto, aunque, como veremos, los objetos manipulados por el servidor y los manipulados por el cliente tengan el mismo nombre, no son idénticos: a veces pueden ser copias entre sí, pero nunca tienen la misma referencia. Modificar un objeto del cliente no tiene ningún efecto sobre el objeto del mismo nombre en el lado del servidor, y viceversa.
El ejemplo [nuxt-07] se obtiene inicialmente mediante una copia del ejemplo [nuxt-01]:

- en [2], vamos a añadir un complemento común al cliente y al servidor;
- en [3], modificaremos ligeramente la página [index];
10.2. El complemento [common / main.js]
El complemento [common / main.js] se ejecuta tanto en el cliente como en el servidor: esto se debe a la siguiente configuración [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- línea 4: la ausencia de la propiedad [mode] hace que el complemento [~/plugins/common/main.js] se ejecute tanto en el cliente como en el servidor: primero en el servidor y después en el cliente;
Este complemento será el siguiente:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// ¿Quién ejecuta este código?
console.log('[main server], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const main = '[main ' + who + ']'
// Número de argumentos
console.log(main + ', il y a', args.length, 'arguments')
// primer argumento
const context = args[0]
// claves del contexto
dumpkeys(main + ', context', context)
// la aplicación
dumpkeys(main + ', context.app', context.app)
// la ruta
dumpkeys(main + ', context.route', context.route)
console.log(main + ', context.route=', context.route)
// el router
dumpkeys(main + ', context.app.router', context.app.router)
// el router.options.routes
dumpkeys(main + ', context.app.router.options.routes', context.app.router.options.routes)
console.log(main + ', context.app.router.options.routes=', context.app.router.options.routes)
// segundo argumento
const inject = args[1]
console.log('inject=', typeof inject)
}
function dumpkeys(message, object) {
// lista de claves de [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// lista de claves
if (object) {
console.log(Object.keys(object))
}
}
- líneas 31-39: la función [dumpkeys] enumera las propiedades del objeto pasado como segundo parámetro. Esta lista va precedida del mensaje pasado como primer parámetro;
- línea 3: queremos saber cuántos argumentos recibe la función. Para ello, utilizamos la notación [...args], que tendrá como efecto colocar los parámetros efectivos de la función en la matriz [args]. Descubriremos que hay dos argumentos;
- línea 5: se muestra quién ejecuta el código, si es el servidor o el cliente;
- línea 6: el ejecutor del código, cliente o servidor;
- línea 7: una cadena de caracteres constante utilizada en los registros;
- línea 12: veremos que el primer argumento que recibe el plugin es el contexto del ejecutor;
- línea 14: lista de claves del objeto [context];
- línea 16: veremos que el objeto [context] tiene una propiedad [app] que representa la aplicación [nuxt];
- línea 18: veremos que el objeto [context] tiene una propiedad [route] que representa la ruta actual del enrutador;
- línea 21: veremos que el objeto [app] tiene una propiedad [router] que representa el enrutador;
- línea 23: el objeto [router.options.routes] representa las diferentes rutas de la aplicación;
- líneas 27-28: el segundo argumento del plugin es la función [inject] que hemos utilizado en el ejemplo [nuxt-06];
10.3. El complemento ejecutado por el servidor
Al ejecutarse, el servidor muestra lo siguiente:
- líneas 11-12: ya hemos tenido ocasión de utilizar las propiedades [base] y [env], cuyos valores proceden del archivo [nuxt.config.js];
- línea 8: la propiedad [app] designa la aplicación [nuxt];
- línea 18: la propiedad [route] indica la ruta actual del enrutador, es decir, la página que va a enviar el servidor;
- línea 13: la solicitud HTTP del navegador del cliente;
- línea 14: la respuesta HTTP del servidor;
La lista de propiedades de [context.app] es la siguiente:
- línea 3: la propiedad [router] nos da acceso al enrutador de la aplicación. Esto es importante en [nuxt], ya que el enrutador lo define el propio [nuxt] y no el desarrollador. Esta propiedad es un acceso que se concede al desarrollador para modificar el enrutador;
La lista de propiedades de [context.route] es la siguiente:
La ruta [context.route] al iniciar el servidor es la siguiente:
- línea 2: se observa que la siguiente página del servidor es [index] y que su ruta es [/] (línea 10);
- línea 22: la propiedad [meta] permite añadir propiedades a las rutas;
Las propiedades del enrutador [context.app.router] del servidor son las siguientes:
En la propiedad [context.app.router.options.routes] se encuentran las diferentes rutas de la aplicación:
Por último, el segundo argumento:
10.4. La página [index] del servidor
La página [index] es la siguiente:
<!-- página principal -->
<template>
<Layout :left="true" :right="true">
<!-- navegación -->
<Navigation slot="left" />
<!-- mensaje-->
<b-alert slot="right" show variant="warning">
Home
</b-alert>
</Layout>
</template>
<script>
/* eslint-disable no-undef */
/* eslint-disable no-console */
/* eslint-disable nuxt/no-env-in-hooks */
import Navigation from '@/components/navigation'
import Layout from '@/components/layout'
export default {
name: 'Home',
// componentes utilizados
components: {
Layout,
Navigation
},
data() {
return {
who: process.server ? 'server' : 'client'
}
},
// ciclo de vida
beforeCreate() {
// cliente y servidor
console.log('[home beforeCreate]')
},
created() {
// cliente y servidor
console.log('[home ' + this.who + ' created]')
this.dumpkeys('[home ' + this.who + ' created], this.$nuxt', this.$nuxt)
this.dumpkeys('[home ' + this.who + ' created], this.$nuxt.context', this.$nuxt.context)
},
beforeMount() {
// solo cliente
console.log('[home ' + this.who + ' beforeMount]')
},
mounted() {
// solo cliente
console.log('[home ' + this.who + ' mounted]')
},
methods: {
dumpkeys(message, object) {
// lista de claves de [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
if (object) {
console.log(Object.keys(object))
}
}
}
}
</script>
- línea 43: ya hemos visto que el contexto de una página se puede encontrar en [this.$nuxt.context];
- línea 42: también se muestran las propiedades del objeto [this.$nuxt];
Al ejecutarse en el servidor, esta página genera los siguientes registros:
Las propiedades del contexto del servidor en la página [index] son las siguientes:
Son las mismas propiedades que las del objeto [context] del complemento.
10.5. El complemento ejecutado por el cliente
Una vez que el servidor ha enviado la página [index] al navegador del cliente, los scripts del cliente toman el control. A continuación, se ejecutará el complemento [main.js]. Estos son los registros:
Encontramos propiedades similares a las que se observan en el lado del servidor, aunque algunas han desaparecido y otras han aparecido. Así, en la línea 4, no aparecen las propiedades [req, res], que correspondían a las solicitudes HTTP del navegador del cliente y a la respuesta HTTP del servidor.
10.6. La página [index] del cliente
La página [index] del cliente genera los siguientes registros:
- línea 4: las propiedades del objeto [this.$nuxt]. Se trata de un objeto complejo con 51 propiedades;
- línea 6: las propiedades del objeto [this.$nuxt.context]. Se observan las mismas propiedades que en el objeto [context] del complemento del cliente;