Obsługa zależności

Wybierz język: Node.js Python

Funkcja w Cloud Functions może używać modułów zewnętrznych i zależności lokalnych. Sposób określania zależności i zarządzania nimi zależy od języka środowiska wykonawczego.

Node.js

Funkcja może używać zewnętrznych modułów Node.js oraz danych lokalnych. Zależnościami w Node.js zarządza się za pomocą npm i są one wyrażone w pliku metadanych o nazwie package.json. Środowiska wykonawcze Node.js w Cloud Functions obsługują instalację za pomocą npm, yarn lub pnpm.

Aby określić zależność funkcji, dodaj ją do pliku package.json.

W tym przykładzie zależność jest wymieniona w pliku package.json:

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

Zależność jest następnie importowana w funkcji:

JavaScript

const onRequest = require("firebase-functions/https");
const escapeHtml = require("escape-html");

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

TypeScript

import { onRequest } from "firebase-functions/https";
import * as escapeHtml from "escape-html";

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

Uwzględnianie lokalnych modułów Node.js

Możesz też dołączyć lokalne moduły Node.js jako część funkcji. Możesz to zrobić, deklarując moduł w pliku package.json za pomocą prefiksu file:. W tym przykładzie mymodule odnosi się do nazwy modułu, a mymoduledir to katalog zawierający moduł:

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

Kod tego modułu lokalnego powinien być przechowywany w innym miejscu niż folder node_modules w katalogu głównym funkcji.

Dodatkowe czynności w przypadku TypeScript

TypeScript jest najbardziej przydatny, gdy używasz bibliotek, które zawierają informacje o typach. Dzięki temu TypeScript może wychwytywać błędy składni, a edytory mogą wyświetlać lepsze sugestie autouzupełniania. Niektóre biblioteki, takie jak firebase-admin i firebase-functions, są dostarczane z definicjami TypeScript.

Wiele bibliotek nie udostępnia własnej definicji TypeScript. Projekt DefinitelyTyped udostępnia definicje najpopularniejszych bibliotek węzłów, które są utrzymywane przez społeczność. DefinitelyTyped publikuje te definicje pod tą samą nazwą pakietu NPM, ale w organizacji „@types”. Możesz na przykład zainstalować informacje o typie dla biblioteki uuid za pomocą tego polecenia:

npm install @types/uuid

Gdy lepiej poznasz TypeScript, możesz połączyć obie instalacje:

npm install uuid @types/uuid

Zależności typów powinny być tego samego rodzaju co zależność biblioteki. Na przykład nie należy zapisywać uuid jako normalnej zależności, a @types/uuid jako zależności deweloperskiej lub równorzędnej.

Wczytywanie modułów Node.js

Użyj funkcji require() w Node.js, aby wczytać dowolny zainstalowany moduł Node.js. Możesz też użyć funkcji require(), aby zaimportować pliki lokalne, które wdrażasz razem z funkcją.

Jeśli piszesz funkcje w języku TypeScript, użyj instrukcji import w ten sam sposób, aby wczytać dowolny zainstalowany moduł Node.js.

Używanie modułów prywatnych

Możesz użyć prywatnego modułu npm, podając ustawienia uwierzytelniania w rejestrze w pliku .npmrc w katalogu funkcji. Jeśli jako menedżera pakietów używasz Yarn w wersji 2 lub nowszej, ten plik ma nazwę .yarnrc.yml.

Moduły prywatne z Artifact Registry

Repozytorium pakietów Node.js w Artifact Registry może hostować prywatne moduły funkcji. Gdy wdrażasz funkcję Google Cloud Functions, proces kompilacji automatycznie generuje dane uwierzytelniające Artifact Registry dla konta usługi Cloud Build. Wystarczy, że podasz repozytorium Artifact Registry w .npmrc bez generowania dodatkowych danych logowania. Przykład:

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

To podejście działa też w przypadku menedżera pakietów Yarn v1. Jeśli używasz Yarn w wersji 2 lub nowszej, wystarczy, że podasz repozytorium Artifact Registry w pliku .yarnrc.yml bez dodatkowych danych logowania. Przykład:

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

Moduły prywatne z innych repozytoriów

W dokumentacji npm znajdziesz informacje o tym, jak tworzyć niestandardowe tokeny dostępu tylko do odczytu. Nie zalecamy używania pliku .npmrc utworzonego w katalogu domowym, ponieważ zawiera on token odczytu i zapisu. Uprawnienia do zapisu nie są wymagane podczas wdrażania i mogą stanowić zagrożenie dla bezpieczeństwa.

Jeśli nie używasz prywatnych repozytoriów, nie dołączaj pliku .npmrc, ponieważ może to wydłużyć czas wdrażania funkcji.

Format pliku

Jeśli używasz pliku .npmrc do ustawienia niestandardowego tokena uwierzytelniania, powinien on zawierać wiersz pokazany poniżej.

//REGISTRY_DOMAIN/:_authToken=AUTH_TOKEN

Zastąp:

  • REGISTRY_DOMAIN: nazwa domeny prywatnego rejestru npm. Jeśli Twoje repozytorium jest hostowane w npmjs.org, ustaw to pole na registry.npmjs.org.
  • AUTH_TOKEN: token autoryzacji rejestru npm. Może to być dosłowna wartość tekstowa tokena lub ciąg tekstowy ${NPM_TOKEN}, który npm zastępuje rzeczywistą wartością tokena ze środowiska.

    Zmienną środowiskową $NPM_TOKEN możesz ustawić za pomocą argumentu --set-build-env-vars polecenia gcloud functions deploy. Więcej informacji o tokenie uwierzytelniania NPM znajdziesz w samouczku NPM dotyczącym modułów prywatnych.


Python

Zależności funkcji Cloud Functions napisanych w Pythonie można określić na 2 sposoby: za pomocą pliku requirements.txt menedżera pakietów pip lub przez spakowanie lokalnych zależności razem z funkcją.

Specyfikacja zależności przy użyciu standardu Pipfile/Pipfile.lock nie jest obsługiwana. Projekt nie powinien zawierać tych plików.

Określanie zależności za pomocą pip

Zależnościami w Pythonie zarządza się za pomocą narzędzia pip i są one wyrażone w pliku metadanych o nazwie requirements.txt. Ten plik musi znajdować się w tym samym katalogu co plik main.py zawierający kod funkcji.

Gdy wdrażasz lub ponownie wdrażasz funkcję, Cloud Functions używa pip do pobrania i zainstalowania najnowszej wersji zależności zadeklarowanych w pliku requirements.txt. Plik requirements.txt zawiera po jednym wierszu na pakiet. Każdy wiersz zawiera nazwę pakietu i opcjonalnie żądaną wersję. Więcej informacji znajdziesz w dokumentacji requirements.txt.

Aby zapobiec wpływowi zmian wersji zależności na kompilację, rozważ przypięcie pakietów zależności do konkretnej wersji.

Oto przykładowy plik requirements.txt:

functions-framework
requests==2.20.0
numpy

Pakowanie zależności lokalnych

Możesz też spakować i wdrożyć zależności razem z funkcją. To podejście jest przydatne, jeśli zależność nie jest dostępna za pomocą menedżera pakietów pip lub jeśli dostęp do internetu w środowisku Cloud Functions jest ograniczony.

Możesz na przykład użyć takiej struktury katalogów:

myfunction/
├── main.py
└── localpackage/
    ├── __init__.py
    └── script.py

Następnie możesz zaimportować kod jak zwykle z localpackage, używając instrukcji import.

# Code in main.py
from localpackage import script

Pamiętaj, że w tym przypadku nie zostaną uruchomione żadne pliki setup.py. Pakiety z tymi plikami nadal można grupować, ale mogą one nie działać prawidłowo na urządzeniu Cloud Functions.