Como processar dependências


Uma função pode usar módulos Node.js externos, bem como dados locais. Dependências no Node.js são gerenciadas com npm e expressas em um arquivo de metadados chamado package.json. Os ambientes de execução Node.js do Cloud Functions são compatíveis com a instalação usando npm, Yarn ou pnpm.

Para especificar uma dependência para sua função, adicione-a ao seu arquivo package.json.

Neste exemplo, uma dependência é listada no arquivo package.json:

{
  "dependencies": {
    "escape-html": "^1.0.3"
  }
}

Em seguida, a dependência é importada na função:

const escapeHtml = require('escape-html');

// Return a greeting with the input HTML-escaped.
exports.hello = functions.https.onRequest((req, res) => {
  res.send(`Hello ${escapeHtml(req.query.name || req.body.name || 'World')}!`);
});
import * as escapeHtml from 'escape-html';

// Return a greeting with the input HTML-escaped.
export let hello = functions.https.onRequest((req, res) => {
  res.send(`Hello ${escapeHtml(req.query.name || req.body.name || 'World')}!`);
}

Como incluir módulos Node.js locais

Também é possível incluir módulos Node.js como parte da sua função. Para isso, declare seu módulo em package.json usando o prefixo file:. No exemplo a seguir, mymodule refere-se ao nome do seu módulo e mymoduledir é o diretório que contém seu módulo:

{
  "dependencies": {
    "mymodule": "file:mymoduledir"
  }
}

O código desse módulo local precisa ser armazenado em algum lugar diferente da pasta node_modules, no diretório raiz da função.

Etapas adicionais do TypeScript

O TypeScript é mais útil com o uso de bibliotecas que têm informações de tipo. Isso permite que o TypeScript capture erros de sintaxe e ofereça aos editores sugestões de preenchimento automático melhores. Algumas bibliotecas, como firebase-admin e firebase-functions, já vêm com definições de TypeScript.

Muitas bibliotecas não oferecem definições próprias do TypeScript. O projeto DefinitelyTyped fornece definições mantidas pela comunidade para as bibliotecas de node mais conhecidas. O DefinitelyTyped publica essas definições com o mesmo nome do pacote NPM, mas dentro da organização "@types". Por exemplo, é possível instalar as informações de tipo para a biblioteca uuid com o seguinte:

npm install @types/uuid

Conforme você se familiarizar com o TypeScript, poderá combinar ambas as instalações:

npm install uuid @types/uuid

As dependências de tipo precisam ser do mesmo tipo que a dependência da biblioteca. Por exemplo, não se deve salvar uuid como uma dependência normal e @types/uuid como uma dependência de desenvolvedor ou de pares.

Como carregar módulos Node.js

Use a função require() do Node.js para carregar qualquer módulo Node.js que tiver instalado. Também é possível usar a função require() para importar arquivos locais implantados com sua função.

Se você estiver escrevendo funções no TypeScript, use a instrução import da mesma maneira para carregar qualquer módulo Node.js instalado.

Usar módulos privados

É possível usar um módulo npm particular. Para isso, basta fornecer configurações para autenticar com o registro em um arquivo .npmrc no diretório da função. Se você estiver usando o Yarn v2 ou versão mais recente como gerenciador de pacotes, esse arquivo será chamado de .yarnrc.yml.

Módulos particulares do Artifact Registry

Um repositório de pacotes Node.js do Artifact Registry pode hospedar módulos particulares para sua função. Quando você implanta uma função do Google Cloud Functions, o processo de compilação gera automaticamente credenciais do Artifact Registry para a conta de serviço do Cloud Build. Você só precisa listar o repositório do Artifact Registry no .npmrc sem gerar outras credenciais. Por exemplo:

@SCOPE:registry=https://REGION_ID-npm.pkg.dev/PROJECT_ID/REPOSITORY_NAME
//REGION_ID-npm.pkg.dev/PROJECT_ID/REPOSITORY_NAME:always-auth=true

Essa abordagem também funciona para o gerenciador de pacotes Yarn v1. Se você estiver usando o Yarn v2 ou mais recente, basta listar o repositório do Artifact Registry no .yarnrc.yml sem credenciais adicionais. Por exemplo:

npmScopes:
  SCOPE:
    npmRegistryServer: https://REGION_ID-npm.pkg.dev/PROJECT_ID/REPOSITORY_NAME
    npmAlwaysAuth: true

Módulos particulares de outros repositórios

A documentação do npm explica como criar tokens personalizados de acesso somente leitura. Não recomendamos usar o arquivo .npmrc criado no diretório principal, porque ele contém um token de leitura/gravação. Permissões de gravação não são necessárias durante a implantação e podem representar um risco de segurança.

Não inclua o arquivo .npmrc se você não estiver usando repositórios particulares, porque isso pode aumentar o tempo de implantação de suas funções.

Formato do arquivo

Se você estiver usando um arquivo .npmrc para definir um token de autenticação personalizado, será necessário que ele inclua a linha mostrada abaixo.

//REGISTRY_DOMAIN/:_authToken=AUTH_TOKEN

Substitua:

  • REGISTRY_DOMAIN: o nome de domínio do registro npm particular. Se o repositório estiver hospedado em npmjs.org, defina esse campo como registry.npmjs.org.
  • AUTH_TOKEN: o token de autorização para o registro npm. Pode ser o valor de texto literal do token ou a string de texto ${NPM_TOKEN}, que npm substitui pelo valor real do token do ambiente.

    É possível definir a variável de ambiente $NPM_TOKEN com o argumento --set-build-env-vars para o comando gcloud functions deploy. Consulte o Tutorial do NPM sobre módulos privados para mais detalhes sobre o token de autenticação do NPM.

Criar uma função com dependências disponibilizadas por pacotes de terceiros

Dependências disponibilizadas por pacotes de terceiros são aquelas em que a origem é incluída diretamente no pacote de código-fonte e recriada com seu próprio código. Use a variável de ambiente de build GOOGLE_VENDOR_NPM_DEPENDENCIES para criar dependências do Node.js disponibilizadas por pacotes de terceiros e pular a instalação delas durante a implantação.

Pré-requisitos para dependências disponibilizadas por pacotes de terceiros

  1. Verifique se você tem uma função ativa com todas as dependências que você quer que sejam definidas pelo fornecedor no arquivo package.json.

  2. Instale essas dependências localmente executando:

        npm install
    
  3. Remova node_modules do arquivo .gcloudignore no diretório de trabalho.

  4. Implante a função, garantindo que a versão do Node.js local seja a mesma especificada durante a implantação.

  5. Implante a função e as dependências disponibilizadas por pacotes de terceiros com o seguinte comando:

      gcloud functions deploy FUNCTION_NAME \
        --runtime RUNTIME_NAME \
        --set-build-env-vars GOOGLE_VENDOR_NPM_DEPENDENCIES=true
    

    Substitua:

    • FUNCTION_NAME: o nome da função de Cloud Functions que você está implantando.
    • RUNTIME_NAME: o nome do ambiente de execução do Node.js para executar a função implantada. Precisa ser a mesma versão do Node.js usada no ambiente de desenvolvimento local.

O pacote do framework do Functions é uma dependência necessária para funções. Para builds mais rápidos, recomendamos a disponibilização de pacotes de terceiros. Caso contrário, ele será transferido por download e instalado quando a função for criada.

Se você especificar um mecanismo NPM no arquivo package.json, será feito o download da versão especificada do NPM no tempo de build. Para suprimir esse comportamento, remova-o do arquivo package.json.