10. Exemplo [nuxt-07]: os contextos do cliente e do servidor
10.1. Présentation
O exemplo [nuxt-07] tem como objetivo explorar o objeto [context] tanto no lado do servidor quanto no lado do cliente. É importante lembrar que esses dois atores das aplicações [nuxt] são separados: eles não compartilham nada, exceto:
- o que o servidor decide enviar ao cliente (na resposta HTTP e na página enviada);
- o que o cliente decide enviar ao servidor (em sua solicitação HTTP);
Portanto, se, como veremos, os objetos manipulados pelo servidor e aqueles manipulados pelo cliente tiverem o mesmo nome, eles não são idênticos: às vezes podem ser cópias um do outro, mas nunca têm a mesma referência. Alterar um objeto do cliente não tem nenhum efeito sobre o objeto com o mesmo nome, no lado do servidor, e vice-versa.
O exemplo [nuxt-07] é obtido inicialmente por meio da cópia do exemplo [nuxt-01]:

- em [2], vamos adicionar um plugin comum ao cliente e ao servidor;
- em [3], vamos modificar um pouco a página [index];
10.2. O plug-in [common / main.js]
O plug-in [common / main.js] é executado tanto pelo cliente quanto pelo servidor: isso se deve à seguinte configuração [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- linha 4: a ausência da propriedade [mode] faz com que o plug-in [~/plugins/common/main.js] seja executado tanto pelo cliente quanto pelo servidor: primeiro pelo servidor, depois pelo cliente;
Esse plug-in será o seguinte:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// quem executa esse 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')
// primeiro argumento
const context = args[0]
// chaves do contexto
dumpkeys(main + ', context', context)
// o aplicativo
dumpkeys(main + ', context.app', context.app)
// a rota
dumpkeys(main + ', context.route', context.route)
console.log(main + ', context.route=', context.route)
// o roteador
dumpkeys(main + ', context.app.router', context.app.router)
// o 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 chaves do [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// lista de chaves
if (object) {
console.log(Object.keys(object))
}
}
- linhas 31-39: a função [dumpkeys] lista as propriedades do objeto passado como segundo parâmetro. Essa lista é precedida pela mensagem passada como primeiro parâmetro;
- linha 3: queremos saber quantos argumentos a função recebe. Para isso, usamos a notação [...args], que terá o efeito de colocar os parâmetros efetivos da função na tabela [args]. Veremos que há dois argumentos;
- linha 5: exibimos quem está executando o código, se é o servidor ou o cliente;
- linha 6: quem está executando o código, cliente ou servidor;
- linha 7: uma constante de cadeia de caracteres usada nos logs;
- linha 12: veremos que o primeiro argumento recebido pelo plugin é o contexto do executor;
- linha 14: lista das chaves do objeto [context];
- linha 16: vamos descobrir que o objeto [context] possui uma propriedade [app] que representa o aplicativo [nuxt];
- linha 18: vamos descobrir que o objeto [context] possui uma propriedade [route] que representa a rota atual do roteador;
- linha 21: vamos descobrir que o objeto [app] possui uma propriedade [router] que representa o roteador;
- linha 23: o objeto [router.options.routes] representa as diferentes rotas do aplicativo;
- linhas 27-28: o segundo argumento do plugin é a função [inject] que utilizamos no exemplo [nuxt-06];
10.3. O plug-in executado pelo servidor
Ao ser executado, o servidor exibe o seguinte:
- linhas 11-12: já tivemos a oportunidade de utilizar as propriedades [base] e [env], cujos valores provêm do arquivo [nuxt.config.js];
- linha 8: a propriedade [app] designa o aplicativo [nuxt];
- linha 18: a propriedade [route] indica a rota atual do roteador, ou seja, a página que o servidor enviará;
- linha 13: a solicitação HTTP do navegador do cliente;
- linha 14: a resposta HTTP do servidor;
A lista de propriedades de [context.app] é a seguinte:
- linha 3: a propriedade [router] nos dá acesso ao roteador do aplicativo. Isso é importante no [nuxt], pois o roteador é definido pelo próprio [nuxt] e não pelo desenvolvedor. Essa propriedade é um acesso concedido ao desenvolvedor para modificar o roteador;
A lista de propriedades de [context.route] é a seguinte:
A rota [context.route] ao iniciar o servidor é a seguinte:
- linha 2: vemos que a próxima página do servidor é [index] e que seu caminho é [/] (linha 10);
- linha 22: a propriedade [meta] permite adicionar propriedades às rotas;
As propriedades do roteador [context.app.router] do servidor são as seguintes:
É na propriedade [context.app.router.options.routes] que se encontram as diferentes rotas do aplicativo:
Por fim, o segundo argumento:
10.4. A página [index] do servidor
A página [index] é a seguinte:
<!-- página principal -->
<template>
<Layout :left="true" :right="true">
<!-- navegação -->
<Navigation slot="left" />
<!-- mensagem-->
<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 e servidor
console.log('[home beforeCreate]')
},
created() {
// cliente e 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() {
// somente cliente
console.log('[home ' + this.who + ' beforeMount]')
},
mounted() {
// somente cliente
console.log('[home ' + this.who + ' mounted]')
},
methods: {
dumpkeys(message, object) {
// lista de chaves de [object]
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
if (object) {
console.log(Object.keys(object))
}
}
}
}
</script>
- linha 43: já vimos que o contexto de uma página pode ser encontrado em [this.$nuxt.context];
- linha 42: também são exibidas as propriedades do objeto [this.$nuxt];
Executada pelo servidor, essa página gera os seguintes logs:
As propriedades do contexto do servidor na página [index] são as seguintes:
São as mesmas propriedades do objeto [context] do plug-in.
10.5. O plug-in executado pelo cliente
Assim que o servidor enviar a página [index] ao navegador do cliente, os scripts do cliente assumem o controle. O plug-in [main.js] será então executado. Esses logs são os seguintes:
Encontramos propriedades semelhantes às encontradas no lado do servidor, com algumas propriedades que desapareceram e outras que surgiram. Assim, na linha 4, não encontramos as propriedades [req, res], que correspondiam às solicitações HTTP do navegador do cliente e à resposta HTTP do servidor.
10.6. A página [index] do cliente
A página [index] do cliente gera os seguintes registros:
- linha 4: as propriedades do objeto [this.$nuxt]. Trata-se de um objeto rico com 51 propriedades;
- linha 6: as propriedades do objeto [this.$nuxt.context]. Encontram-se as mesmas propriedades que no objeto [context] do plug-in do cliente;