Layers, layers, layers...
Layers, layers, layers...
Uma das principais funcionalidades presentes no Nuxt 3 é a Layers.
Com ela você pode extender várias aplicações Nuxt resultando em uma só. Assim, é possível reutilizar componentes, composables, configurações, páginas, funções.
Dá pra fazer extends local, de um pacote NPM e até de um repositório git.
export default defineNuxtConfig({
extends: [
'../base', // Extend from a local layer
'@my-themes/awesome', // Extend from an installed npm package
'github:my-themes/awesome#v1', // Extend from a git repository
]
});Mas como pode ser usado?
Eu costumo usar com monorepos e mantenho as rotas de API, páginas e componentes em três projetos separados.
É uma ótima maneira de organizar o projeto para se trabalhar com vários times. Onde cada time, por exemplo, trabalha em um escopo diferente dentro da mesma aplicação final sem interferir no trabalho de outro time. Já que estarão em repositórios diferentes.
Como o Nuxt 3 foi feito baseado no incrível NitroJS, é possível fazer deploy para Firebase, Vercel, etc. com o benefício do serverless sem muita dor de cabeça, alterando apenas algumas linhas. Então a camada que contém a API é executada do lado do servidor com Cloud Functions no Firebase por exemplo. E com NitroJS é possível ter SSR sem complicações.
Exemplo com monorepo
Crie um novo projeto como yarn init -y -p
Altere o package.json adicionando workspaces:
"private": true{
"name": "@myapp/layers",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"private": true,
"workspaces": [
"layers/**"
]
}Vamos criar o diretório com os pacotes do nosso workspace
mkdir layers
cd layersAgora vamos criar nosso app base que vai fazer extends das layers
npx nuxi@latest init appAgora vamos criar nossa layer de API que vai rodar no Firebase Cloud Function.
Pra facilitar vamos usar o template de layer do nuxi
npx nuxi@latest init --template layer serverLayer server
Aqui vamos alterar o package.json fazendo o seguinte:
- Alterar o nome para estar mais de acordo com o workspace
{
"name": "@myapp/server",
"type": "module",
"version": "0.0.1",
"main": "./nuxt.config.ts",
"scripts": {
"dev": "nuxi dev .playground",
"build": "nuxt build .playground",
"generate": "nuxt generate .playground",
"preview": "nuxt preview .playground",
"lint": "eslint .",
"postinstall": "nuxt prepare .playground"
},
"devDependencies": {
"@nuxt/eslint-config": "^0.1.1",
"eslint": "^8.28.0",
"nuxt": "^3.0.0",
"typescript": "^4.9.3"
}
}Layer app
Aqui vamos alterar o package.json fazendo o seguinte:
- Adicionar
versionpara funcionar com o workspace doyarn - Remover o
privateadicionado por padrão pelonuxi - Alterar o nome do pacote para estar mais de acordo com o workspace
- Adicionar o
@myapp/servercomo dependência. Essa é a nossa layer
{
"name": "@myapp/app",
"version": "0.0.1",
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
},
"devDependencies": {
"@myapp/server": "0.0.1",
"@types/node": "^18",
"nuxt": "^3.4.3"
}
}Alteramos agora o nuxt.config.ts para ele fazer extends da nossa layer server.
export default defineNuxtConfig({
extends: [
'@myapp/server'
]
})Pronto, já temos uma estrutura de reutilização de código com as layers do Nuxt
Instalação
Agora a partir da raiz do nosso workspace executamos a instalação das dependências
yarn installImplementações
Agora vem a parte legal, podemos usar as rotas de API de servidor do Nuxt para construir as funções que vão ser usadas no Firebase Cloud Function.
Essa implementação vamos manter na layer server. Nela estará todas as rotas da API que serão executadas do lado do servidor.
Para isso, basta criar os arquivos das rotas dentro do diretório server/api na nossa layer server.
export default defineEventHandler((event) => {
return {
api: 'works'
}
})Testando
Pronto, se quisermos testar, basta rodar o script dev da layer @myapp/app:
yarn workspace @myapp/app devE então abrir no navegador http://localhost:3000/api/hello que você vai ver a resposta implementada na layer server em layers/server/server/api/hello.ts
Perceba que rodamos o @myapp/app mas a implementação da rota da API está no @myapp/server. E o Nuxt mesclou as layers para gente.
Deploy
Para fazer deploy é tão simples como implementar as layers.
Nitro
Nuxt 3 foi construído sobre o NitroJS.
E o que é legal, ele tem presets de deploy para vários serviços, incluindo Firebase.
Pra configurar no nosso @myapp/app com preset do Firebase, vamos alterar o nuxt.config.ts
export default defineNuxtConfig({
extends: [
'@myapp/server'
],
nitro: {
preset: 'firebase'
}
})Instalar as dependências do Firebase
yarn workspace @myapp/app add -D firebase-admin firebase-functions firebase-functions-testAgora só configurar o firebase com o firebase-tools:
firebase login
firebase init hostingQuando for perguntado sobre qual diretório contém a aplicação a ser enviada para o Firebase, dizer que é a .output/public
Depois de concluído, altere o firebase.json para habilitar a renderização com Cloud Functions
{
"functions": { "source": ".output/server" },
"hosting": [
{
"site": "<your_project_id>",
"public": ".output/public",
"cleanUrls": true,
"rewrites": [{ "source": "**", "function": "server" }]
}
]
}Pronto, agora só fazer deploy que sua aplicação vai ter renderização do lado do servidor, APIs e tudo isso usando layers!!
Pra saber mais sobre os presets no Nitro só ler aqui
Descubra mais sobre Layers aqui