You are browsing Nuxt 2 docs. Go to Nuxt 3 docs, or learn more about Nuxt 2 Long Term Support.

← Para trás

Criando um Módulo de Nuxt

Módulos são funções que são chamadas sequencialmente quando se estiver inicializando a Nuxt. A abstração espera todos módulos serem carregados antes de continuar. Neste sentido, os módulos podem personalizar quase qualquer espeto do seu projeto. Vamos criar um módulo que usa ngrok to receber uma URL pública que você pode partilhar enquanto estiveres trabalhando em Desenvolvimento.

|
Criando um Módulo de Nuxt

Módulos são funções que são chamadas sequencialmente quando se estiver inicializando a Nuxt. A abstração espera todos módulos serem carregados antes de continuar. Desta maneira, os módulos podem personalizar quase qualquer aspeto do seu projeto. Os módulos de Nuxt podem ser incorporados dentro de pacotes de npm. Isto os torna fáceis de reutilizá-los através dos projetos e partilhá-los com a comunidade.

Alguma vez estiveste a trabalhar em alguma coisa e ocorreu um bug ou apenas precisaste receber a aprovação de alguém?. Existem algumas opções para alcançar isto tal como desdobrando a tua aplicação ou criando um CodeSandbox . Mas uma outra opção é partilhar o teu localhost para que assim que tu realizares mudanças ao vivo no modo de desenvolvimento, ela possa ser vista por qualquer pessoa que tiver a ligação, não importa onde elas estejam. Nós podemos utilizar ngrok para alcançar isto.

Vamos criar um módulo que utiliza ngrok para que tu recebas uma URL pública que pode ser vista na interface de linha de comando da Nuxt quando executares o commando dev.

Este módulo já foi criado e publicado e tu podes utilizá-lo sem o criares por ti mesmo instalando o módulo @nuxtjs/ngrok . Tu podes também saltar direto para o código consultando a nossa Demonstração no CodeSandbox . No entanto se estiveres interessado em ver como ele foi criado ou quiseres criar o teu próprio módulo então continue lendo.

Como isto funciona?

ngrok criará um túnel http-https-tcp. Consulte o pacote de npm de ngrok para obter mais detalhes. Nós precisamos ser capazes de conectar à uma porta ngrok quando o servidor de Nuxt estiver ouvindo. Uma vez que nós recebemos uma URL pública nós queremos imprimi-la para interface de linha de comando da Nuxt assim nós podemos facilmente clicá-la para abrir e partilhá-la.

interface de linha de comando da nuxt

Vamos começar

Para utilizar um módulo personalizado dentro da nossa aplicação nós temos que criar um pasta modules se ainda não tiveres uma. Dentro dela vamos criar uma pasta chamada ngrok e adicionar um ficheiro index.js dentro dela. Tu podes utilizar a teu editor para criar estas pastas e ficheiros ou utilizar os comandos abaixo.

mkdir modules modules/ngrok
touch modules/ngrok/index.js

No sentido de utilizar o nosso módulo nós precisaremos registá-la adicionando ela na secção buildModules do nosso ficheiro nuxt.config.js. Os buildModules apenas são importados durante o tempo de desenvolvimento e não em construção o que é perfeito para o nosso módulo visto que nós apenas precisamos dele a funcionar no modo desenvolvimento.

nuxt.config.js
export default {
  buildModules: ['~/modules/ngrok']
}

Como nós utilizaremos o pacote ngrok de npm nós precisaremos instalar como uma dependência de desenvolvimento.

Yarn
yarn add --dev ngrok
NPM
npm install --dev ngrok

Criando o nosso módulo

Agora que nós temos instalado e registado tudo nós podemos seguir adiante e criar o nosso módulo. A primeira coisa que nós precisamos fazer é importar o ngrok a partir da nossa pasta node_modules para dentro nosso ficheiro index.js do nosso módulo.

modules/ngrok/index.js
import ngrok from 'ngrok'

Nós podemos então criar uma função utilizando export default que permite-nos utilizar esta função em um outro ficheiro.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {}

Dentro desta função nós podemos começar desconstruindo a nuxt e tornando-a igual a this, o que significa que nós não teremos que escrever this.nuxt toda vez que nos referimos a nuxt.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  const { nuxt } = this

  // Aqui vai o código do meu módulo de nuxt
}

Investigando as nuxt.options

Nós apenas queremos executar o ngrok em modo de desenvolvimento e não em produção então como faríamos isto?

Primeiro vamos registar na nossa consola nuxt.options assim nós podemos utilizar todas as opções de nuxt que estiverem disponíveis para nós. Isto é, o nuxt.config.js misturado com os valores predefinidos.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  const { nuxt } = this

  console.log(nuxt.options)

  // Aqui vai o código do meu módulo de nuxt
}

Há muito valores aqui. O que nós queremos é uma maneira de saber quando é que nós estamos no modo de desenvolvimento e verás a partir da consola que em nossa nuxt.options nós temos dev definida para true. Isto significa nós podemos adicionar uma expressão if para verificar se dev é false e retornar se nós não estivermos em modo de desenvolvimento.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  const { nuxt } = this

  // Não iniciar `ngrok` em produção
  if (nuxt.options.dev === false) {
    return
  }

  // Mais vindo abaixo :)
}

Iniciar o túnel ngrok quando o servidor da Nuxt estiver ouvindo

Nós queremos iniciar o túnel ngrok quando o servidor de nuxt estivermos ouvindo. Para fazer isto nós precisamos de uma maneira de prender dentro da Nuxt e ouvir para uma porta assim nós podemos conectar-nos. É onde os gatilhos da Nuxt entram. Gatilhos da Nuxt estão os ouvintes para os eventos de Nuxt. Nós utilizaremos o nuxt.hook() passando o valor de listen seguida de uma função assíncrona. Nesta função nós precisamos passar no servidor, seguida da porta.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  // [...]

  // https://v2.nuxt.com/docs/internals-glossary/internals-nuxt#hooks
  nuxt.hook('listen', async function (server, { port }) {

  })
}

Nós então esperamos a conexão de ngrok passar o valor da porta e atribuí-la à nossa URL, que está definida fora da função. Nós podemos agora executar um console.log dentro da nossa função para ver o resultado da nossa URL.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  // [...]

  let url

  // https://v2.nuxt.com/docs/internals-glossary/internals-nuxt#hooks
  nuxt.hook('listen', async function (server, { port }) {

    url = await ngrok.connect(port)

    // Aqui nós temos nossa URL pública
    console.log(url)
  })
}

Agora se tu executares o comando dev e abrir a tua consola verás a tua URL do ngrok. Abrir aquela URL mostrará o teu sítio no modo de desenvolvimento.

Adicionado um authtoken

Ainda que isto funcione nós podemos correr para alguns problemas que dizem respeito ao máximo de conexão e outras limitações e portanto é melhor configurar um authtoken que pode ser feito de graça a partir do sítio da ngrok.

Uma vez que temos o nosso simbólico nós podemos configurar o nosso ficheiro .env e adicionar o nosso simbólico.

.env
NGROK_TOKEN=my-authtoken-from-ngrok
Não se esqueça de garantir que o teu ficheiro .env seja adicionado ao teu .gitignore.

Nós podemos agora definir uma constante options que é igual as opções da propriedade ngrok do nosso nuxt.config.js ou igual a um objeto vazio no caso de nós não definirmos quaisquer opções. Nós também adicionamos uma constante token que é igual ao NGROK_TOKEN do nosso ficheiro .env ou options.token que é a mesma que nuxt.options.ngrok.token, no caso em que este valor foi definido diretamente em nossa propriedade ngrok no nosso nuxt.config.js.

Nós podemos então esperar o authtoken do ngrok passar o valor simbólico.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  // [...]

  // Leia a propriedade `ngrok` definida em `nuxt.config.js`
  const options = nuxt.options.ngrok || {}
  const token = process.env.NGROK_TOKEN || options.token

  // [...]
}

Nós podemos então esperar o authtoken do ngrok passar o valor do token que nós definimos acima.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  // [...]

  // Leia a propriedade `ngrok` definida em `nuxt.config.js`
  const options = nuxt.options.ngrok || {}
  const token = process.env.NGROK_TOKEN || options.token

  // https://v2.nuxt.com/docs/internals-glossary/internals-nuxt#hooks
  nuxt.hook('listen', async function (server, { port }) {

    if(token){
      await ngrok.authtoken(token)
    }

    url = await ngrok.connect(port)

    // Aqui nós temos a nossa URL pública
    console.log(url)
  })
}

ngrok em ação

Mas isto está realmente funcionando? Se eu mudar qualquer coisa em desenvolvimento verão elas naquela URL? Vamos espreitar. Se nós irmos para nossa página index e adicionarmos algum texto. Por exemplo "URL from ngrok:" verás agora que a mudança no teu localhost e também na URL do ngrok que imprimiste na consola. Que fantástico.

pages/index.vue
<p>URL from ngrok:</p>

Vamos adicionar nossa URL do ngrok ao nosso modelo de marcação de Vue. Nós podemos obter o acesso para a nossa URL do ngrok passando o publicRuntimeConfig que está então acessível utilizando $config do contexto. Nós fazemos isto passando a nossa URL para a nuxt.options.publicRuntimeConfig.ngrok. Nós podemos agora remover a nossa console.log visto que isto não é mais necessário.

modules/ngrok/index.js
import ngrok from 'ngrok'

export default function () {
  // [...]

  // https://v2.nuxt.com/docs/internals-glossary/internals-nuxt#hooks
  nuxt.hook('listen', async function (server, { port }) {

    if(token){
      await ngrok.authtoken(token)
    }

    url = await ngrok.connect(port)

    // Adiciona a URL pública ao `publicRuntimeConfig`
    nuxt.options.publicRuntimeConfig.ngrok = { url }

  })
}

Nós podemos agora acessar isto em nosso modelo de marcação de Vue utilizando $config e se nós envolvermos ela em um marcador de ligação então ela será clicável.

modules/ngrok/index.js
<template>
  <p>URL from ngrok: <a :href="$config.ngrok.url">{{ $config.ngrok.url }}</a></p>
</template>

Vamos executar o servidor de desenvolvimento e agora tu deves ver a tua URL do ngrok impressa na página. Qua fantástico.

Adicionar a nossa URL a CLI de Nuxt

Em geral nós provavelmente não iremos querer imprimir a URL para a página. Seria muito melhor se nós pudéssemos adicioná-lo à CLI de Nuxt assim nós podemos vê-la toda vez que nós executamos o comando dev e seriamos capazes de clicá-lo e abri-lo a partir de lá. Nós podemos então partilhar aquela ligação com quem nós quisermos sem ter que expor ela em nosso ficheiro .vue ou em nossa consola.

Nós podemos acessar a CLI através da nuxt.options. Tu podes acompanhar isto registando a nuxt.options à consola e procurando pela CLI. Se tu o fizeres tu verás que nós temos uma propriedade badgeMessages . Esta é a caixa verde que mostra-nos as mensagens do Ambiente, Interpretação e Alvo como também em qual parta a aplicação está ouvindo.

Nós podemos utilizar o método push() para empurrar nossa URL para a CLI de Nuxt.

modules/ngrok/index.js
// [...]
nuxt.hook('listen', async function (server, { port }) {
    // [...]

    // Adiciona a URL pública à caixa de Nuxt na CLI
    nuxt.options.cli.badgeMessages.push(url)

  })
})

Agora quando nós executamos o comando dev a nossa a URL aparece na caixa verde. Claro que nós podemos melhorar isto mais adiante adicionando algum texto antes da URL assim os nossos utilizadores saberão o que é.

modules/ngrok/index.js
// [...]
nuxt.hook('listen', async function (server, { port }) {
    // [...]

    // Adiciona a URL pública à caixa de Nuxt na CLI
    nuxt.options.cli.badgeMessages.push(`Public URL: ${url}`)

  })
})

Nós podemos também mudar a cor desta ligação e sublinhá-la utilizando um pacote chamado chalk o qual permite-nos estilizar o nosso terminal.

modules/ngrok/index.js
import ngrok from 'ngrok'
import chalk from 'chalk'

// [...]

Nós podemos então utilizar chalk.underline.yellow ou outra cor qualquer do pacote chalk.

modules/ngrok/index.js
import ngrok from 'ngrok'
import chalk from 'chalk'
// [...]

  nuxt.hook('listen', async function (server, { port }) {
    // [...]

    // Mudar a cor utilizando o `chalk`
    nuxt.options.cli.badgeMessages.push(
      `Public URL: ${chalk.underline.yellow(url)}`
    )
  })
}

Agora verás que quando estiveres executando o comando dev nós teremos a nossa URL Pública com a ligação sublinhada e em uma cor amarela. Então esta pode ser clicada e aberta e claro partilhada com alguém, em qualquer lugar no mundo assim elas podem assistir ao vivo as tuas mudanças no modo de desenvolvimento.

interface de linha de comando da nuxt

Fechando o nosso ngrok

Devemos sempre fechar a nossa conexão de ngrok quando fechamos a Nuxt. Para fazer isto nós podemos prendê-lo a Nuxt e procurar por quando fechará e executar uma função para desconectar a ngrok.

modules/ngrok/index.js
// [...]
export default function () {
  // [...]

  nuxt.hook('close', function () {
    url && ngrok.disconnect()
  })
}

Exemplo de código completo

modules/ngrok/index.js
import ngrok from 'ngrok'
import chalk from 'chalk'

export default function () {
  const { nuxt } = this

  // Não iniciar o `ngrok` em produção
  if (nuxt.options.dev === false) {
    return
  }

  // Leia a propriedade `ngrok` definida em `nuxt.config.js`
  const options = nuxt.options.ngrok || {}
  const token = process.env.NGROK_TOKEN || options.token

  // https://v2.nuxt.com/docs/internals-glossary/internals-nuxt#hooks
  nuxt.hook('listen', async function (server, { port }) {

    if(token){
      await ngrok.authtoken(token)
    }


    url = await ngrok.connect(port)

    // Adiciona a URL pública ao `publicRuntimeConfig`
    nuxt.options.publicRuntimeConfig.ngrok = { url }

    // Adiciona a URL pública a caixa da Nuxt na CLI
    nuxt.options.cli.badgeMessages.push(
    `Public URL: ${chalk.underline.yellow(url)}`
    )

  })

  nuxt.hook('close', function () {
    url && ngrok.disconnect()
  })
}

Conclusão

Nós criamos o nosso módulo local o qual podemos utilizar em nosso projeto. Isto algumas vezes é o suficiente mas algumas vezes nós queremos partilhar o nosso módulo através de projetos ou melhor, com a Comunidade da Nuxt. Para fazer isto precisamos criar o nosso módulo utilizando um modelo de módulo e publicá-lo na npm.

Desde hoje nós estamos trabalhando no melhoramento deste modelo para torná-lo mais amigável ao utilizador. Todos os módulos são criados utilizando a TypeScript e devem conter testes, documentação e um exemplo.

Exploração mais adiante