التعامل مع التبعيات

اختيار اللغة: Node.js Python

يمكن أن تستخدم دالة Cloud Functions وحدات خارجية ومهام تابعة محلية. تعتمد طريقة تحديد التبعيات وإدارتها على لغة وقت التشغيل.

Node.js

يُسمح للدالة باستخدام وحدات Node.js خارجية بالإضافة إلى البيانات المحلية. تتم إدارة التبعيات في Node.js باستخدام npm ويتم التعبير عنها في ملف بيانات وصفية يُسمى package.json. تتيح بيئات تشغيل Node.js في Cloud Functions إمكانية التثبيت باستخدام npm أو yarn أو pnpm.

لتحديد تبعية لدالتك، أضِفها إلى ملف package.json.

في هذا المثال، تم إدراج تبعية في ملف package.json:

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

بعد ذلك، يتم استيراد التبعية في الدالة:

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")}!`);
});

تضمين وحدات Node.js المحلية

يمكنك أيضًا تضمين وحدات Node.js محلية كجزء من الدالة. يمكنك تحقيق ذلك من خلال تعريف الوحدة في package.json باستخدام البادئة file:. في المثال التالي، يشير mymodule إلى اسم الوحدة وmymoduledir إلى الدليل الذي يحتوي على الوحدة:

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

يجب تخزين رمز الوحدة المحلية في مكان آخر غير المجلد node_modules ضمن الدليل الجذر للدالة.

خطوات إضافية لاستخدام TypeScript

تساعدك TypeScript بشكل كبير عند استخدام مكتبات تتضمّن معلومات عن الأنواع. يتيح ذلك لـ TypeScript رصد الأخطاء في البنية، كما يتيح للمحرّرات تقديم اقتراحات أفضل للإكمال التلقائي. تتضمّن بعض المكتبات، مثل firebase-admin وfirebase-functions، تعريفات TypeScript.

لا توفّر العديد من المكتبات تعريف TypeScript الخاص بها. يوفر مشروع DefinitelyTyped تعريفات يتم صيانتها من قِبل المنتدى لأكثر مكتبات Node شيوعًا. تنشر DefinitelyTyped هذه التعريفات تحت اسم حزمة NPM نفسه، ولكن داخل مؤسسة "@types". على سبيل المثال، يمكنك تثبيت معلومات النوع لمكتبة uuid باستخدام ما يلي:

npm install @types/uuid

عندما تصبح أكثر دراية بلغة TypeScript، قد تجد نفسك تجمع بين طريقتَي التثبيت التاليتَين:

npm install uuid @types/uuid

يجب أن تكون تبعيات النوع من النوع نفسه الذي تعتمد عليه المكتبة. على سبيل المثال، يجب عدم حفظ uuid كاعتمادية عادية و@types/uuid كاعتمادية تطوير أو اعتمادية متساوية.

تحميل وحدات Node.js

استخدِم دالة Node.js require() لتحميل أي وحدة Node.js مثبَّتة. يمكنك أيضًا استخدام الدالة require() لاستيراد الملفات المحلية التي تنشرها مع الدالة.

إذا كنت تكتب دوالاً في TypeScript، استخدِم عبارة import بالطريقة نفسها لتحميل أي وحدة Node.js ثبّتها.

استخدام الوحدات الخاصة

يمكنك استخدام وحدة npm خاصة من خلال توفير إعدادات للمصادقة مع السجلّ في ملف .npmrc ضمن دليل الدالة. إذا كنت تستخدم الإصدار 2 من Yarn أو إصدارًا أحدث كمدير حِزم، سيكون اسم هذا الملف .yarnrc.yml.

الوحدات الخاصة من Artifact Registry

يمكن لمستودع حِزم Node.js في Artifact Registry استضافة وحدات خاصة بدالتك. عند نشر دالة في Google Cloud Functions، تنشئ عملية الإنشاء تلقائيًا بيانات اعتماد Artifact Registry لحساب خدمة Cloud Build. ما عليك سوى إدراج مستودع Artifact Registry في .npmrc بدون إنشاء بيانات اعتماد إضافية. على سبيل المثال:

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

يعمل هذا النهج أيضًا مع مدير حِزم Yarn v1. إذا كنت تستخدم الإصدار 2 من Yarn أو إصدارًا أحدث، ما عليك سوى إدراج مستودع Artifact Registry في .yarnrc.yml بدون بيانات اعتماد إضافية. على سبيل المثال:

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

الوحدات الخاصة من المستودعات الأخرى

توضّح مستندات npm كيفية إنشاء رموز مميّزة مخصّصة للقراءة فقط. ننصح بعدم استخدام الملف .npmrc الذي تم إنشاؤه في دليل الصفحة الرئيسية لأنّه يحتوي على رمز مميز للقراءة والكتابة. لا تكون أذونات الكتابة مطلوبة أثناء عملية النشر، وقد تؤدي إلى تعرّضك لمخاطر أمنية.

لا تضمِّن ملف .npmrc إذا كنت لا تستخدم مستودعات خاصة، لأنّ ذلك قد يزيد من وقت نشر الدوال.

تنسيق الملف

إذا كنت تستخدم ملف .npmrc لضبط رمز مميّز مخصّص للمصادقة، يجب أن يتضمّن السطر الموضّح أدناه.

//REGISTRY_DOMAIN/:_authToken=AUTH_TOKEN

استبدال:

  • REGISTRY_DOMAIN: اسم نطاق سجلّ npm الخاص بك. إذا كان مستودعك مستضافًا على npmjs.org، اضبط هذا الحقل على registry.npmjs.org.
  • AUTH_TOKEN: رمز التفويض الخاص بمستودع npm. يمكن أن تكون هذه القيمة إما قيمة نصية حرفية للرمز المميّز أو سلسلة نصية ${NPM_TOKEN}، والتي يستبدلها npm بقيمة الرمز المميّز الفعلية من البيئة.

    يمكنك ضبط متغيّر البيئة $NPM_TOKEN باستخدام الوسيطة --set-build-env-vars في الأمر gcloud functions deploy. راجِع البرنامج التعليمي حول الوحدات الخاصة في NPM للحصول على مزيد من التفاصيل حول رمز المصادقة في NPM.


Python

هناك طريقتان لتحديد التبعيات في Cloud Functions المكتوبة بلغة Python: استخدام ملف requirements.txt الخاص بأداة إدارة الحزم pip أو تجميع التبعيات المحلية مع الدالة.

لا تتوافق مواصفات التبعية التي تستخدم معيار Pipfile/Pipfile.lock. يجب ألا يتضمّن مشروعك هذه الملفات.

تحديد التبعيات باستخدام pip

تتم إدارة التبعيات في Python باستخدام pip ويتم التعبير عنها في ملف بيانات وصفية يُسمى requirements.txt. يجب أن يكون هذا الملف في الدليل نفسه الذي يتضمّن ملف main.py الذي يحتوي على رمز الدالة.

عند نشر الدالة أو إعادة نشرها، تستخدم Cloud Functions أداة pip لتنزيل أحدث إصدار من التبعيات وتثبيته كما هو موضّح في ملف requirements.txt. يحتوي الملف requirements.txt على سطر واحد لكل حزمة. يحتوي كل سطر على اسم الحزمة، ويمكن أن يحتوي أيضًا على الإصدار المطلوب. لمزيد من التفاصيل، يُرجى الاطّلاع على requirements.txt.

لمنع تأثُّر الإصدار بتغييرات إصدار الاعتمادية، ننصحك بتثبيت حِزم الاعتمادية على إصدار معيّن.

في ما يلي مثال على ملف requirements.txt:

functions-framework
requests==2.20.0
numpy

تجميع المهام التابعة المحلية

يمكنك أيضًا تجميع التبعيات ونشرها مع الدالة. يكون هذا الأسلوب مفيدًا إذا لم تكن التبعية متاحة من خلال أداة إدارة الحِزم pip أو إذا كان الوصول إلى الإنترنت في بيئة Cloud Functions محدودًا.

على سبيل المثال، يمكنك استخدام بنية دليل مثل ما يلي:

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

يمكنك بعد ذلك استيراد الرمز كالمعتاد من localpackage باستخدام عبارة import التالية.

# Code in main.py
from localpackage import script

يُرجى العِلم أنّ هذا الأسلوب لن يشغّل أي ملفات setup.py. سيظل بإمكانك تجميع الحِزم التي تتضمّن هذه الملفات، ولكن قد لا تعمل بشكلٍ صحيح على Cloud Functions.