10. Exemplo [nuxt-07]: Contextos do Cliente e do Servidor
10.1. Introdução
O exemplo [nuxt-07] tem como objetivo explorar o objeto [context] tanto no lado do servidor como no lado do cliente. É importante lembrar que estes dois componentes das aplicações [nuxt] são separados: eles não partilham nada, exceto:
- o que o servidor decide enviar para o cliente (na resposta HTTP e na página renderizada);
- o que o cliente decide enviar para o servidor (na sua solicitação HTTP);
Assim, como veremos, embora os objetos tratados pelo servidor e aqueles tratados pelo cliente tenham o mesmo nome, não são idênticos: podem, por vezes, ser cópias um do outro, mas nunca têm a mesma referência. Modificar um objeto do lado do cliente não tem efeito sobre o objeto com o mesmo nome no lado do servidor, e vice-versa.
O exemplo [nuxt-07] é inicialmente obtido através da cópia do exemplo [nuxt-01]:

- em [2], vamos adicionar um plugin partilhado pelo cliente e pelo servidor;
- em [3], iremos modificar ligeiramente a página [index];
10.2. O plugin [common / main.js]
O plugin [common / main.js] é executado tanto pelo cliente como pelo servidor: isto deve-se à seguinte configuração em [nuxt.config.js]:
/*
** Plugins to load before mounting the App
*/
plugins: [{ src: '~/plugins/common/main.js' }],
- linha 4: a ausência da propriedade [mode] significa que o plugin [~/plugins/common/main.js] será executado tanto pelo cliente como pelo servidor: primeiro pelo servidor, depois pelo cliente;
Este plugin será o seguinte:
/* eslint-disable no-undef */
/* eslint-disable no-console */
export default function(...args) {
// who executes this code?
console.log('[main server], process.server=', process.server, 'process.client=', process.client)
const who = process.server ? 'server' : 'client'
const main = '[main ' + who + ']'
// number of arguments
console.log(main + ', il y a', args.length, 'arguments')
// 1st argument
const context = args[0]
// key context
dumpkeys(main + ', context', context)
// the application
dumpkeys(main + ', context.app', context.app)
// the road
dumpkeys(main + ', context.route', context.route)
console.log(main + ', context.route=', context.route)
// the router
dumpkeys(main + ', context.app.router', context.app.router)
// on 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)
// 2nd argument
const inject = args[1]
console.log('inject=', typeof inject)
}
function dumpkeys(message, object) {
// list of [object] keys
const ligne = 'Liste des clés [' + message + ']'
console.log(ligne)
// kEY LIST
if (object) {
console.log(Object.keys(object))
}
}
- linhas 31–39: a função [dumpkeys] lista as propriedades do objeto passado como segundo parâmetro. Esta 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 colocará os parâmetros reais da função na matriz [args]. Veremos que existem dois argumentos;
- linha 5: exibimos quem está a executar o código, o servidor ou o cliente;
- linha 6: o executor do código, cliente ou servidor;
- linha 7: uma constante de cadeia de caracteres utilizada nos registos;
- linha 12: veremos que o primeiro argumento recebido pelo plugin é o contexto do executor;
- linha 14: lista de chaves para o objeto [context];
- linha 16: veremos que o objeto [context] possui uma propriedade [app] que representa a aplicação [nuxt];
- linha 18: veremos que o objeto [context] possui uma propriedade [route] que representa a rota atual do router;
- linha 21: vamos ver que o objeto [app] tem uma propriedade [router] que representa o router;
- linha 23: o objeto [router.options.routes] representa as várias rotas da aplicação;
- linhas 27–28: o segundo argumento do plugin é a função [inject] que utilizámos no exemplo [nuxt-06];
10.3. O plugin executado pelo servidor
Quando 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 ficheiro [nuxt.config.js];
- linha 8: a propriedade [app] refere-se à aplicação [nuxt];
- linha 18: a propriedade [route] refere-se à rota atual do router, ou seja, a página que o servidor irá enviar;
- linha 13: o pedido HTTP do navegador do cliente;
- linha 14: a resposta HTTP do servidor;
A lista de propriedades [context.app] é a seguinte:
- linha 3: a propriedade [router] dá-nos acesso ao router da aplicação. Isto é importante no [Nuxt], uma vez que o router é definido pelo próprio [Nuxt] e não pelo programador. Esta propriedade permite ao programador modificar o router;
A lista de propriedades [context.route] é a seguinte:
A rota [context.route] quando o servidor é iniciado é a seguinte:
- linha 2: vemos que a próxima página no servidor é [index] e que o seu caminho é [/] (linha 10);
- linha 22: a propriedade [meta] permite adicionar propriedades às rotas;
As propriedades do [context.app.router] do servidor são as seguintes:
As várias rotas da aplicação encontram-se na propriedade [context.app.router.options.routes]:
Por fim, o segundo argumento:
10.4. A página [index] do servidor
A página [index] é a seguinte:
<!-- page principale -->
<template>
<Layout :left="true" :right="true">
<!-- navigation -->
<Navigation slot="left" />
<!-- message-->
<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',
// components used
components: {
Layout,
Navigation
},
data() {
return {
who: process.server ? 'server' : 'client'
}
},
// life cycle
beforeCreate() {
// client and server
console.log('[home beforeCreate]')
},
created() {
// client and 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() {
// customer only
console.log('[home ' + this.who + ' beforeMount]')
},
mounted() {
// customer only
console.log('[home ' + this.who + ' mounted]')
},
methods: {
dumpkeys(message, object) {
// list of [object] keys
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 exibimos as propriedades do objeto [this.$nuxt];
Quando executada pelo servidor, esta página gera os seguintes registos:
As propriedades do contexto do servidor na página [index] são as seguintes:
Estas são as mesmas propriedades do objeto [context] do plugin.
10.5. O plugin executado pelo cliente
Assim que o servidor enviar a página [index] para o navegador do cliente, os scripts do lado do cliente assumem o controlo. O plugin [main.js] será então executado. Estes registos são os seguintes:
Encontramos propriedades semelhantes às encontradas no lado do servidor, com algumas propriedades em falta e outras a aparecerem. Por exemplo, na linha 4, as propriedades [req, res] — que eram os pedidos HTTP do navegador do cliente e a resposta HTTP do servidor — estão em falta.
10.6. A página [index] do cliente
A página [index] do cliente produz os seguintes registos:
- linha 4: as propriedades do objeto [this.$nuxt]. É um objeto rico com 51 propriedades;
- linha 6: as propriedades do objeto [this.$nuxt.context]. Estas são as mesmas propriedades encontradas no objeto [context] do plugin do cliente;