10. Esempio [nuxt-07]: i contesti client e server
10.1. Présentation
L’esempio [nuxt-07] mira a esplorare l’oggetto [context] sia dal lato server che dal lato client. Non bisogna dimenticare che questi due attori delle applicazioni [nuxt] sono separati: non condividono nulla tranne:
- ciò che il server decide di inviare al client (nella risposta HTTP e nella pagina inviata);
- ciò che il client decide di inviare al server (nella sua richiesta HTTP);
Pertanto, se, come vedremo, gli oggetti gestiti dal server e quelli gestiti dal client hanno lo stesso nome, non sono identici: a volte possono essere copie l’uno dell’altro, ma non hanno mai lo stesso riferimento. Modificare un oggetto client non ha alcun effetto sull’oggetto con lo stesso nome, lato server, e viceversa.
L’esempio [nuxt-07] si ottiene inizialmente copiando l’esempio [nuxt-01]:

- in [2], aggiungeremo un plugin comune al client e al server;
- in [3], modificheremo leggermente la pagina [index];
10.2. Il plugin [common / main.js]
Il plugin [common / main.js] viene eseguito sia dal client che dal server: ciò è dovuto alla seguente configurazione [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- riga 4: l’assenza della proprietà [mode] fa sì che il plugin [~/plugins/common/main.js] venga eseguito sia dal client che dal server: prima dal server, poi dal client;
Tale plugin sarà il seguente:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// chi esegue questo codice?
console.log('[main server], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const main = '[main ' + who + ']'
// numero di argomenti
console.log(main + ', il y a', args.length, 'arguments')
// primo argomento
const context = args[0]
// chiavi del contesto
dumpkeys(main + ', context', context)
// l'applicazione
dumpkeys(main + ', context.app', context.app)
// la route
dumpkeys(main + ', context.route', context.route)
console.log(main + ', context.route=', context.route)
// il router
dumpkeys(main + ', context.app.router', context.app.router)
// il 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)
// secondo argomento
const inject = args[1]
console.log('inject=', typeof inject)
}
function dumpkeys(message, object) {
// elenco delle chiavi di [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// elenco delle chiavi
if (object) {
console.log(Object.keys(object))
}
}
- righe 31-39: la funzione [dumpkeys] elenca le proprietà dell’oggetto passato come secondo parametro. Questo elenco è preceduto dal messaggio passato come primo parametro;
- riga 3: si vuole sapere quanti argomenti riceve la funzione. A tal fine, si utilizza la notazione [...args], che avrà l’effetto di inserire i parametri effettivi della funzione nell’array [args]. Si scoprirà che ci sono due argomenti;
- riga 5: si visualizza chi esegue il codice, se il server o il client;
- riga 6: l’esecutore del codice, client o server;
- riga 7: una stringa costante utilizzata nei log;
- riga 12: vedremo che il primo argomento ricevuto dal plugin è il contesto dell’esecutore;
- riga 14: elenco delle chiavi dell’oggetto [context];
- riga 16: scopriremo che l’oggetto [context] ha una proprietà [app] che rappresenta l’applicazione [nuxt];
- riga 18: scopriremo che l’oggetto [context] ha una proprietà [route] che rappresenta il percorso corrente del router;
- riga 21: scopriremo che l’oggetto [app] ha una proprietà [router] che rappresenta il router;
- riga 23: l’oggetto [router.options.routes] rappresenta i diversi percorsi dell’applicazione;
- righe 27-28: il secondo argomento del plugin è la funzione [inject] che abbiamo utilizzato nell’esempio [nuxt-06];
10.3. Il plugin eseguito dal server
All’esecuzione, il server visualizza quanto segue:
- righe 11-12: abbiamo già avuto modo di utilizzare le proprietà [base] e [env], i cui valori provengono dal file [nuxt.config.js];
- riga 8: la proprietà [app] indica l’applicazione [nuxt];
- riga 18: la proprietà [route] indica il percorso corrente del router, ovvero la pagina che il server invierà;
- riga 13: la richiesta HTTP del browser client;
- riga 14: la risposta HTTP del server;
L'elenco delle proprietà di [context.app] è il seguente:
- riga 3: la proprietà [router] ci consente di accedere al router dell'applicazione. Questo è importante in [nuxt] poiché il router è definito dallo stesso [nuxt] e non dallo sviluppatore. Questa proprietà consente allo sviluppatore di modificare il router;
L'elenco delle proprietà di [context.route] è il seguente:
Il percorso [context.route] all’avvio del server è il seguente:
- riga 2: si vede che la pagina successiva del server è [index] e che il suo percorso è [/] (riga 10);
- riga 22: la proprietà [meta] consente di aggiungere proprietà alle rotte;
Le proprietà del router [context.app.router] del server sono le seguenti:
È nella proprietà [context.app.router.options.routes] che si trovano le diverse rotte dell’applicazione:
Infine, il secondo argomento:
10.4. La pagina [index] del server
La pagina [index] è la seguente:
<!-- pagina principale -->
<template>
<Layout :left="true" :right="true">
<!-- navigazione -->
<Navigation slot="left" />
<!-- messaggio-->
<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',
// componenti utilizzati
components: {
Layout,
Navigation
},
data() {
return {
who: process.server ? 'server' : 'client'
}
},
// ciclo di vita
beforeCreate() {
// client e server
console.log('[home beforeCreate]')
},
created() {
// client e server
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 client
console.log('[home ' + this.who + ' beforeMount]')
},
mounted() {
// solo client
console.log('[home ' + this.who + ' mounted]')
},
methods: {
dumpkeys(message, object) {
// elenco delle chiavi di [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
if (object) {
console.log(Object.keys(object))
}
}
}
}
</script>
- riga 43: abbiamo già visto che il contesto di una pagina può essere trovato in [this.$nuxt.context];
- riga 42: vengono visualizzate anche le proprietà dell’oggetto [this.$nuxt];
Una volta eseguita dal server, questa pagina genera i seguenti log:
Le proprietà del contesto server nella pagina [index] sono le seguenti:
Si tratta delle stesse proprietà presenti nell’oggetto [context] del plugin.
10.5. Il plugin eseguito dal client
Una volta che il server ha inviato la pagina [index] al browser del client, subentrano gli script client. A questo punto verrà eseguito il plugin [main.js]. I log sono i seguenti:
Si riscontrano proprietà analoghe a quelle presenti sul lato server, con alcune proprietà scomparse e altre apparse. Pertanto, alla riga 4, non sono presenti le proprietà [req, res], che corrispondevano alle richieste HTTP del browser client e alla risposta HTTP del server.
10.6. La pagina [index] del client
La pagina [index] del client genera i seguenti log:
- riga 4: le proprietà dell’oggetto [this.$nuxt]. Si tratta di un oggetto complesso con 51 proprietà;
- riga 6: le proprietà dell’oggetto [this.$nuxt.context]. Si riscontrano le stesse proprietà presenti nell’oggetto [context] del plugin client;