Como usar a especificação de implantação do Amplify Hosting para configurar a saída da compilação - AWS Amplify Hospedagem

Como usar a especificação de implantação do Amplify Hosting para configurar a saída da compilação

A especificação de implantação do Amplify Hosting é uma especificação baseada em sistema de arquivos que define a estrutura de diretórios que facilita as implantações no Amplify Hosting. Um framework pode gerar essa estrutura esperada de diretórios como saída do seu comando de compilação, permitindo que o framework aproveite as vantagens dos serviços primitivos do Amplify Hosting. A Amplify Hosting entende a estrutura do pacote de implantação e o implanta adequadamente.

Para ver uma demonstração em vídeo que explica como usar a especificação de implantação, consulte Como hospedar qualquer site usando o AWS Amplify no canal da Amazon Web Services no YouTube.

Veja a seguir um exemplo da estrutura de pastas que o Amplify espera para o pacote de implantação. Em um alto nível, ele tem uma pasta chamada static, uma pasta chamada compute e um arquivo de manifesto de implantação chamado deploy-manifest.json.

.amplify-hosting/ ├── compute/ │ └── default/ │ ├── chunks/ │ │ └── app/ │ │ ├── _nuxt/ │ │ │ ├── index-xxx.mjs │ │ │ └── index-styles.xxx.js │ │ └── server.mjs │ ├── node_modules/ │ └── server.js ├── static/ │ ├── css/ │ │ └── nuxt-google-fonts.css │ ├── fonts/ │ │ ├── font.woff2 │ ├── _nuxt/ │ │ ├── builds/ │ │ │ └── latest.json │ │ └── entry.xxx.js │ ├── favicon.ico │ └── robots.txt └── deploy-manifest.json

Compatibilidade do Amplify com primitivo de SSR

A especificação de implantação do Amplify Hosting define um contrato que mapeia de perto os seguintes primitivos.

Ativos estáticos

Fornece aos frameworks a capacidade de hospedar arquivos estáticos.

Computação

Fornece aos framework a capacidade de executar um servidor HTTP Node.js na porta 3000.

Otimização de imagem

Fornece aos framework um serviço para otimizar imagens em runtime.

Regras de roteamento

Fornece aos framework um mecanismo para mapear caminhos de solicitação de entrada para destinos específicos.

O diretório .amplify-hosting/static

Você deve colocar no diretório .amplify-hosting/static todos os arquivos estáticos acessíveis ao público que deverão ser oferecidos diretamente do URL da aplicação. Os arquivos dentro desse diretório serão oferecidos por meio do primitivo de ativos estáticos.

Os arquivos estáticos podem ser acessados na raiz (/) do URL da aplicação sem nenhuma alteração em seu conteúdo, nome de arquivo ou extensão. Além disso, os subdiretórios são preservados na estrutura do URL e aparecem antes do nome do arquivo. Por exemplo, .amplify-hosting/static/favicon.ico será oferecido de https://myAppId.amplify-hostingapp.com/favicon.ico, enquanto .amplify-hosting/static/_nuxt/main.js será oferecido de https://myAppId.amplify-hostingapp.com/_nuxt/main.js.

Se um framework for compatível com a capacidade de modificar o caminho base da aplicação, ele deverá prefixar o caminho base aos ativos estáticos dentro do diretório .amplify-hosting/static. Por exemplo, se o caminho base for /folder1/folder2, a saída de compilação para um ativo estático chamado main.css será .amplify-hosting/static/folder1/folder2/main.css.

O diretório .amplify-hosting/compute

Um único recurso computacional é representado por um único subdiretório chamado default contido no diretório .amplify-hosting/compute. O caminho é .amplify-hosting/compute/default. Esse recurso computacional é mapeado para o primitivo computacional do Amplify Hosting.

O conteúdo do subdiretório default deve estar em conformidade com as regras a seguir.

  • É necessário ter um arquivo na raiz do subdiretório default para atuar como ponto de entrada para o recurso computacional.

  • O arquivo do ponto de entrada deve ser um módulo Node.js e iniciar um servidor HTTP que escute na porta 3000.

  • Você pode colocar outros arquivos no subdiretório default e fazer referência a eles no código no arquivo do ponto de entrada.

  • O conteúdo do subdiretório deve ser independente. O código no módulo de ponto de entrada não pode fazer referência a nenhum módulo fora do subdiretório. Observe que os frameworks podem agrupar seus servidores HTTP da maneira que quiserem. Se for possível iniciar o processo de computação com o comando node server.js, com server.js is indicando o nome do arquivo de entrada, diretamente do subdiretório, o Amplify vai considerar que a estrutura do diretório está em conformidade com a especificação de implantação.

O Amplify Hosting agrupa e implanta todos os arquivos dentro do subdiretório default em um recurso computacional provisionado. Cada recurso computacional recebe 512 MB de armazenamento temporário. Esse armazenamento não é compartilhado entre instâncias de execução, mas é compartilhado entre invocações subsequentes na mesma instância de execução. As instâncias de execução estão limitadas a um tempo máximo de 15 minutos de execução, e o único caminho gravável dentro da instância de execução é o diretório /tmp. O tamanho compactado de cada pacote de recursos computacionais não pode ultrapassar 220 MB. Por exemplo, o subdiretório .amplify/compute/default não pode ultrapassar 220 MB quando compactado.

O arquivo .amplify-hosting/deploy-manifest.json

Use o arquivo deploy-manifest.json para armazenar os detalhes da configuração e os metadados de uma implantação. Um arquivo deploy-manifest.json deve incluir, no mínimo, um atributo version, o atributo routes com uma rota abrangente especificada e o atributo framework com metadados de framework especificados.

A definição de objeto a seguir demonstra a configuração de um manifesto de implantação.

type DeployManifest = { version: 1; routes: Route[]; computeResources?: ComputeResource[]; imageSettings?: ImageSettings; framework: FrameworkMetadata; };

Os tópicos a seguir descrevem os detalhes e o uso de cada atributo no manifesto de implantação.

Como usar o atributo de versão

O atributo version define a versão da especificação de implantação que você está implementando. No momento, a única versão da especificação de implantação do Amplify Hosting é a versão 1. O exemplo de JSON a seguir demonstra como usar o atributo version.

"version": 1

Como usar o atributo routes

O atributo routes permite que as estruturas aproveitem o primitivo de regras de roteamento do Amplify Hosting. As regras de roteamento fornecem um mecanismo para rotear os caminhos de solicitação de entrada para um destino específico no pacote de implantação. As regras de roteamento determinam somente o destino de uma solicitação recebida e são aplicadas depois que a solicitação é transformada pelas regras de regravação e redirecionamento. Para obter mais informações sobre como o Amplify Hosting processar regravações e redirecionamentos, consulte Configuração de redirecionamentos e regravações para uma aplicação do Amplify.

As regras de roteamento não regravam nem transformam a solicitação. Se uma solicitação recebida corresponder ao padrão de caminho de uma rota, a solicitação será roteada no estado em que se encontra para o destino da rota.

As regras de roteamento especificadas na matriz routes devem obedecer às seguintes regras.

  • É necessário haver uma rota abrangente especificada. Uma rota abrangente tem o padrão /* que corresponde a todas as solicitações recebidas.

  • A matriz routes pode conter no máximo 25 itens.

  • É necessário especificar uma rota Static ou uma rota Compute.

  • Se você especificar uma rota Static, o diretório .amplify-hosting/static deverá existir.

  • Se você especificar uma rota Compute, o diretório .amplify-hosting/compute deverá existir.

  • Se você especificar uma rota ImageOptimization, também deverá especificar uma rota Compute. Isso é necessário porque a otimização de imagem ainda não é compatível com aplicações puramente estáticas.

A definição de objeto a seguir demonstra a configuração para o objeto Route.

type Route = { path: string; target: Target; fallback?: Target; }

A tabela a seguir descreve as propriedades do objeto Route.

Chave Tipo Obrigatório Descrição

caminho

String

Sim

Define um padrão que corresponde aos caminhos da solicitação recebida (excluindo a string de consulta).

O caminho pode ter até 255 caracteres.

Um caminho deve começar com a barra /.

Um caminho pode conter qualquer um dos seguintes caracteres: [A-Z], [a-z], [0-9],[ _-.*$/~"'@:+].

Somente os seguintes caracteres curinga são compatíveis para correspondência de padrão:

  • * (corresponde a 0 ou mais caracteres)

  • O padrão /* é chamado de padrão abrangente e corresponderá a todas as solicitações recebidas.

target

Destino

Sim

Um objeto que define o destino para o qual rotear a solicitação correspondente.

Se houver a especificação de uma rota Compute, deverá haver um ComputeResource correspondente.

Se houver a especificação de uma rota ImageOptimization, também deverá haver um imageSettings especificado.

fallback

Destino

Não

Um objeto que define o destino para o fallback se o destino original retornar um erro 404.

O tipo target e o tipo fallback não podem ser iguais para uma rota específica. Por exemplo, não é permitido fazer o fallback de Static para Static. Os fallbacks só são compatíveis com solicitações GET que não tenham um corpo. Se houver um corpo na solicitação, ele será descartado durante o fallback.

A definição de objeto a seguir demonstra a configuração para o objeto Target.

type Target = { kind: TargetKind; src?: string; cacheControl?: string; }

A tabela a seguir descreve as propriedades do objeto Target.

Chave Tipo Obrigatório Descrição

kind

Targetkind

Sim

Um enum que define o tipo de destino. Os valores válidos são Static, Compute e ImageOptimization.

src

String

Sim para Compute

Não para outros primitivos

Uma string que especifica o nome do subdiretório no pacote de implantação que contém o código executável do primitivo. Válido e necessário somente para o primitivo Compute.

O valor deve apontar para um dos recursos computacionais presentes no pacote de implantação. No momento, o único valor compatível para esse campo é default.

cacheControl

String

Não

Uma string que especifica o valor do cabeçalho Cache-Control a ser aplicado à resposta. Válido somente para os primitivos Static e ImageOptimization.

O valor especificado é substituído por cabeçalhos personalizados. Para obter mais informações sobre os cabeçalhos personalizados do Amplify Hosting, consulte Configuração de cabeçalhos personalizados para uma aplicação do Amplify.

nota

Esse cabeçalho Cache-Control é aplicado somente a respostas com êxito com um código de status definido como 200 (OK).

A definição de objeto a seguir demonstra o uso da enumeração TargetKind.

enum TargetKind { Static = "Static", Compute = "Compute", ImageOptimization = "ImageOptimization" }

A lista a seguir especifica os valores válidos para a enumeração TargetKind.

Estático

Roteia as solicitações para o primitivo de ativos estáticos.

Computação

Roteia as solicitações para o primitivo de computação.

ImageOptimization

Roteia as solicitações para o primitivo de otimização de imagem.

O exemplo de JSON a seguir demonstra como usar o atributo routes com várias regras de roteamento especificadas.

"routes": [ { "path": "/_nuxt/image", "target": { "kind": "ImageOptimization", "cacheControl": "public, max-age=3600, immutable" } }, { "path": "/_nuxt/builds/meta/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/_nuxt/builds/*", "target": { "cacheControl": "public, max-age=1, immutable", "kind": "Static" } }, { "path": "/_nuxt/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/*.*", "target": { "kind": "Static" }, "fallback": { "kind": "Compute", "src": "default" } }, { "path": "/*", "target": { "kind": "Compute", "src": "default" } } ]

Para obter mais informações sobre como especificar regras de roteamento em seu manifesto de implantação, consulte Práticas recomendadas para a configuração de regras de roteamento.

Como usar o atributo computerResources

O atributo computeResources permite que as estruturas forneçam metadados sobre os recursos computacionais provisionados. Cada recurso computacional deve ter uma rota correspondente associada.

A definição de objeto a seguir demonstra o uso do objeto ComputeResource.

type ComputeResource = { name: string; runtime: ComputeRuntime; entrypoint: string; }; type ComputeRuntime = 'nodejs16.x' | 'nodejs18.x' | 'nodejs20.x';

A tabela a seguir descreve as propriedades do objeto ComputeResource.

Chave Tipo Obrigatório Descrição

name

String

Sim

Especifica o nome do recurso de computação. O nome deve corresponder ao nome do subdiretório dentro de .amplify-hosting/compute directory.

O único valor válido para a versão 1 da especificação de implantação é default.

runtime

ComputeRuntime

Sim

Define o runtime do recurso computacional provisionado.

Os valores válidos são nodejs16.x, nodejs18.x e nodejs20.x.

entrypoint

String

Sim

Especifica o nome do arquivo inicial com base no qual o código será executado para o recurso computacional especificado. O arquivo deve existir dentro do subdiretório que representa um recurso computacional.

Se você tiver uma estrutura de diretórios semelhante ao seguinte exemplo.

.amplify-hosting |---compute | |---default | |---index.js

O JSON para o atributo computeResource será semelhante ao seguinte exemplo.

"computeResources": [ { "name": "default", "runtime": "nodejs16.x", "entrypoint": "index.js", } ]

Como usar o atributo imageSettings

O atributo imageSettings permite que os frameworks personalizem o comportamento do primitivo de otimização de imagem, que fornece otimização sob demanda de imagens em runtime.

A definição de objeto a seguir demonstra o uso do objeto ImageSettings.

type ImageSettings = { sizes: number[]; domains: string[]; remotePatterns: RemotePattern[]; formats: ImageFormat[]; minumumCacheTTL: number; dangerouslyAllowSVG: boolean; }; type ImageFormat = 'image/avif' | 'image/webp' | 'image/png' | 'image/jpeg';

A tabela a seguir descreve as propriedades do objeto ImageSettings.

Chave Tipo Obrigatório Descrição

sizes

Number[]

Sim

Uma matriz de larguras de imagem compatíveis.

domains

String[]

Sim

Uma matriz de domínios externos permitidos que podem usar a otimização de imagem. Deixe a matriz vazia para permitir que somente o domínio de implantação use a otimização de imagem.

remotePatterns

RemotePattern[]

Sim

Uma matriz de padrões externos permitidos que podem usar a otimização de imagem. Semelhante aos domínios, mas fornece mais controle com expressões regulares (regex).

formats

ImageFormat[]

Sim

Uma variedade de formatos de imagem de saída permitidos.

minimumCacheTTL

Número

Sim

A duração do cache em segundos para as imagens otimizadas.

dangerouslyAllowSVG

Booleano

Sim

Permite URLs de imagem de entrada em SVG. Esse recurso está desabilitado por padrão para fins de segurança.

A definição de objeto a seguir demonstra o uso do objeto RemotePattern.

type RemotePattern = { protocol?: 'http' | 'https'; hostname: string; port?: string; pathname?: string; }

A tabela a seguir descreve as propriedades do objeto RemotePattern.

Chave Tipo Obrigatório Descrição

protocolo

String

Não

O protocolo do padrão remoto permitido.

Os valores válidos são http ou https.

hostname

String

Sim

O nome de host do padrão remoto permitido.

Você pode especificar um caractere literal ou curinga. Um “*” único corresponde a um único subdomínio. Um “**” duplo corresponde a qualquer número de subdomínios. O Amplify não permite curingas gerais que especifiquem apenas “**”.

porta

String

Não

A porta do padrão remoto permitido.

pathname

String

Não

O nome de caminho do padrão remoto permitido.

O exemplo a seguir demonstra o atributo imageSettings.

"imageSettings": { "sizes": [ 100, 200 ], "domains": [ "example.com" ], "remotePatterns": [ { "protocol": "https", "hostname": "example.com", "port": "", "pathname": "/**", } ], "formats": [ "image/webp" ], "minumumCacheTTL": 60, "dangerouslyAllowSVG": false }

Como usar o atributo framework

Use o atributo framework para especificar os metadados do framework.

A definição de objeto a seguir demonstra a configuração para o objeto FrameworkMetadata.

type FrameworkMetadata = { name: string; version: string; }

A tabela a seguir descreve as propriedades do objeto FrameworkMetadata.

Chave Tipo Obrigatório Descrição

name

String

Sim

O nome do framework.

versão

String

Sim

A versão do framework.

Ele deve ser uma string válida de versionamento semântico (semver).

Práticas recomendadas para a configuração de regras de roteamento

As regras de roteamento fornecem um mecanismo para rotear os caminhos de solicitação de entrada para destinos específicos no pacote de implantação. Em um pacote de implantação, os criadores do framework podem emitir arquivos para a saída da compilação que são implantados em qualquer um dos seguintes destinos:

  • Primito de ativos estáticos: os arquivos estão contidos no diretório .amplify-hosting/static.

  • Primitivo de computação: os arquivos estão contidos no diretório .amplify-hosting/compute/default.

Os criadores do framework também fornecem uma matriz de regras de roteamento no arquivo de manifesto de implantação. Cada regra na matriz é comparada com a solicitação recebida em ordem de passagem sequencial, até que haja uma correspondência. Quando houver uma regra correspondente, a solicitação será roteada para o destino especificado na regra correspondente. Como opção, é possível especificar um destino de fallback para cada regra. Se o destino original retornar um erro 404, a solicitação será roteada para o destino de fallback.

A especificação de implantação exige que a última regra na ordem de passagem seja uma regra abrangente. Uma regra abrangente é especificada com o caminho /*. Se a solicitação recebida não corresponder a nenhuma das rotas anteriores na matriz de regras de roteamento, a solicitação será roteada para o destino da regra abrangente.

Para frameworks de SSR como Nuxt.js, o destino da regra abrangente deve ser a computação primitiva. Isso ocorre porque os aplicações de SSR têm páginas renderizadas no lado do servidor com rotas que não são previsíveis no momento da compilação. Por exemplo, se uma aplicação Nuxt.js tiver uma página em /blog/[slug] na qual [slug] esteja um parâmetro de rota dinâmica. O destino regra abrangente é a única maneira de rotear solicitações para essas páginas.

Por outro lado, é possível usar padrões de caminho específicos para direcionar rotas que sejam conhecidas no momento da compilação. Por exemplo, Nuxt.js fornece ativos estáticos do caminho /_nuxt. Isso significa que o caminho /_nuxt/* pode ser direcionado por uma regra específica de roteamento que roteia solicitações para o primitivo de ativos estáticos.

Roteamento de pasta pública

A maioria dos frameworks de SSR oferece a capacidade de fornecer ativos estáticos mutáveis diretamente de uma pasta public. Em geral, arquivos como favicon.ico e robots.txt são mantidos dentro da pasta public e são fornecidos diretamente do URL raiz da aplicação. Por exemplo, o arquivo favicon.ico é fornecido diretamente de https://example.com/favicon.ico. Observe que não há um padrão de caminho previsível para esses arquivos. Eles são quase que totalmente ditados pelo nome do arquivo. A única maneira de direcionar arquivos dentro da pasta public é usar a rota abrangente. No entanto, o destino geral da rota precisa ser o primitivo de computação.

Recomendamos uma das seguintes abordagens para gerenciar sua pasta public.

  1. Use um padrão de caminho para direcionar caminhos de solicitação que contenham extensões de arquivo. Por exemplo, você pode usar /*.* para direcionar todos os caminhos de solicitação que contenham uma extensão de arquivo.

    Observe que essa abordagem pode não ser confiável. Por exemplo, se houver arquivos sem extensões de arquivo dentro da pasta public, eles não serão direcionados por essa regra. Outro problema a ser observado com essa abordagem é que a aplicação pode ter páginas com pontos em seus nomes. Por exemplo, uma página em /blog/2021/01/01/hello.world será direcionada pela regra /*.* . Isso não é ideal, pois a página não é um ativo estático. No entanto, você pode adicionar um destino alternativo a essa regra para garantir que a solicitação retorne para o primitivo computacional quando houver um erro 404 do primitivo estático.

    { "path": "/*.*", "target": { "kind": "Static" }, "fallback": { "kind": "Compute", "src": "default" } }
  2. Identifique os arquivos na pasta public no momento da compilação e emita uma regra de roteamento para cada arquivo. Essa abordagem não é escalável, pois há um limite de 25 regras imposto pela especificação de implantação.

    { "path": "/favicon.ico", "target": { "kind": "Static" } }, { "path": "/robots.txt", "target": { "kind": "Static" } }
  3. Recomende que os usuários do framework armazenem todos os ativos estáticos mutáveis dentro de uma subpasta dentro da pasta public.

    No exemplo a seguir, o usuário pode armazenar todos os ativos estáticos mutáveis dentro da pasta public/assets. Em seguida, é possível usar uma regra de roteamento com o padrão de caminho /assets/* para direcionar todos os ativos estáticos mutáveis dentro da pasta public/assets.

    { "path": "/assets/*", "target": { "kind": "Static" } }
  4. Especifique um fallback estático para a rota abrangente. Essa abordagem tem desvantagens que são descritas com mais detalhes na próxima seção Roteamento abrangente de fallback.

Roteamento abrangente de fallback

Para frameworks de SSR como Nuxt.js, no qual uma rota abrangente é especificada para o destino primitivo de computação, os criadores do framework podem considerar a especificação de um fallback estático para a rota abrangente a fim de solucionar o problema de roteamento da pasta public. No entanto, esse tipo de regra de roteamento interrompe as páginas 404 renderizadas no lado do servidor. Por exemplo, se o usuário final visitar uma página que não exista, a aplicação vai renderizar uma página 404 com um código de status 404. No entanto, se a rota abrangente tiver um fallback estático, a página 404 não será renderizada. Em vez disso, a solicitação retornará para o primitivo estático e ainda terminará com um código de status 404, mas a página 404 não será renderizada.

{ "path": "/*", "target": { "kind": "Compute", "src": "default" }, "fallback": { "kind": "Static" } }

Roteamento de caminho base

Espera-se que frameworks com a capacidade de modificar o caminho base da aplicação possam prefixar o caminho base aos ativos estáticos dentro do diretório .amplify-hosting/static. Por exemplo, se o caminho base for /folder1/folder2, a saída de compilação para um ativo estático chamado main.css será .amplify-hosting/static/folder1/folder2/main.css.

Isso significa que também é necessário atualizar as regras de roteamento para refletir o caminho base. Por exemplo, se o caminho base for /folder1/folder2, a regra de roteamento para os ativos estáticos na pasta public terá a seguinte aparência.

{ "path": "/folder1/folder2/*.*", "target": { "kind": "Static" } }

Da mesma forma, também é necessário prefixar o caminho base nas rotas do lado do servidor. Por exemplo, se o caminho base for /folder1/folder2, a regra de roteamento para a rota /api terá a seguinte aparência.

{ "path": "/folder1/folder2/api/*", "target": { "kind": "Compute", "src": "default" } }

No entanto, o caminho base não deverá ser prefixado à rota abrangente. Por exemplo, se o caminho base for /folder1/folder2, a rota abrangente permanecerá da seguinte maneira.

{ "path": "/*", "target": { "kind": "Compute", "src": "default" } }

Exemplos de rotas do Nuxt.js

Veja a seguir um exemplo de arquivo deploy-manifest.json para uma aplicação Nuxt que demonstra como especificar regras de roteamento.

{ "version": 1, "routes": [ { "path": "/_nuxt/image", "target": { "kind": "ImageOptimization", "cacheControl": "public, max-age=3600, immutable" } }, { "path": "/_nuxt/builds/meta/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/_nuxt/builds/*", "target": { "cacheControl": "public, max-age=1, immutable", "kind": "Static" } }, { "path": "/_nuxt/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/*.*", "target": { "kind": "Static" }, "fallback": { "kind": "Compute", "src": "default" } }, { "path": "/*", "target": { "kind": "Compute", "src": "default" } } ], "computeResources": [ { "name": "default", "entrypoint": "server.js", "runtime": "nodejs18.x" } ], "framework": { "name": "nuxt", "version": "3.8.1" } }

Veja a seguir um exemplo de arquivo deploy-manifest.json para Nuxt que demonstra como especificar regras de roteamento que incluem caminhos base.

{ "version": 1, "routes": [ { "path": "/base-path/_nuxt/image", "target": { "kind": "ImageOptimization", "cacheControl": "public, max-age=3600, immutable" } }, { "path": "/base-path/_nuxt/builds/meta/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/base-path/_nuxt/builds/*", "target": { "cacheControl": "public, max-age=1, immutable", "kind": "Static" } }, { "path": "/base-path/_nuxt/*", "target": { "cacheControl": "public, max-age=31536000, immutable", "kind": "Static" } }, { "path": "/base-path/*.*", "target": { "kind": "Static" }, "fallback": { "kind": "Compute", "src": "default" } }, { "path": "/*", "target": { "kind": "Compute", "src": "default" } } ], "computeResources": [ { "name": "default", "entrypoint": "server.js", "runtime": "nodejs18.x" } ], "framework": { "name": "nuxt", "version": "3.8.1" } }

Para obter mais informações sobre o uso do atributo routes, consulte Como usar o atributo routes.