การจัดการทรัพยากร Dependency

เลือกภาษา Node.js Python

ฟังก์ชัน Cloud Functions สามารถใช้โมดูลภายนอกและทรัพยากร Dependency ในเครื่องได้ วิธีระบุและจัดการทรัพยากร Dependency จะขึ้นอยู่กับภาษาของรันไทม์

Node.js

ฟังก์ชันจะได้รับอนุญาตให้ใช้โมดูล Node.js ภายนอกและข้อมูลในเครื่อง ระบบจะจัดการทรัพยากร Dependency ใน Node.js ด้วย npm และแสดงในไฟล์ข้อมูลเมตาที่ชื่อ package.json รันไทม์ Node.js ของ Cloud Functions รองรับการติดตั้งโดยใช้ npm, yarn หรือ pnpm

หากต้องการระบุทรัพยากร Dependency สำหรับฟังก์ชัน ให้เพิ่มลงในไฟล์ package.json

ในตัวอย่างนี้ ทรัพยากร Dependency จะแสดงอยู่ในไฟล์ package.json ดังนี้

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

จากนั้นระบบจะนำเข้าทรัพยากร Dependency ในฟังก์ชัน ดังนี้

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 มีคำจำกัดความที่ชุมชนดูแลรักษาสำหรับไลบรารีโหนดที่ได้รับความนิยมมากที่สุด DefinitelyTyped จะเผยแพร่คำจำกัดความเหล่านี้ภายใต้ชื่อแพ็กเกจ NPM เดียวกัน แต่จะอยู่ภายในองค์กร "@types" ตัวอย่างเช่น คุณสามารถติดตั้งข้อมูลประเภทสำหรับไลบรารี uuid โดยใช้คำสั่งต่อไปนี้

npm install @types/uuid

เมื่อคุ้นเคยกับ TypeScript มากขึ้น คุณอาจพบว่าตัวเองรวมการติดตั้งทั้ง 2 รายการเข้าด้วยกัน ดังนี้

npm install uuid @types/uuid

ทรัพยากร Dependency ของประเภทควรเป็นประเภทเดียวกับทรัพยากร Dependency ของไลบรารี ตัวอย่างเช่น คุณไม่ควรบันทึก uuid เป็นทรัพยากร Dependency ปกติ และ @types/uuid เป็นทรัพยากร Dependency สำหรับนักพัฒนาซอฟต์แวร์หรือทรัพยากร Dependency แบบเพียร์

กำลังโหลดโมดูล Node.js

ใช้ฟังก์ชัน Node.js require() เพื่อโหลดโมดูล Node.js ที่คุณติดตั้งไว้ นอกจากนี้ คุณยังใช้ฟังก์ชัน require() เพื่อนำเข้าไฟล์ในเครื่องที่ติดตั้งใช้งานควบคู่ไปกับฟังก์ชันได้ด้วย

หากคุณเขียนฟังก์ชันใน TypeScript ให้ใช้คำสั่ง import ในลักษณะเดียวกันเพื่อโหลดโมดูล Node.js ที่คุณติดตั้งไว้

การใช้โมดูลส่วนตัว

คุณสามารถใช้โมดูล npm ส่วนตัวได้โดยระบุการตั้งค่าสำหรับการตรวจสอบสิทธิ์กับรีจิสทรีในไฟล์ .npmrc ในไดเรกทอรีของฟังก์ชัน หากคุณใช้ Yarn v2 ขึ้นไปเป็นเครื่องมือจัดการแพ็กเกจ ไฟล์นี้จะมีชื่อว่า .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 ด้วย หากใช้ Yarn v2 ขึ้นไป คุณเพียงแค่ต้องระบุที่เก็บ 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

การระบุทรัพยากร Dependency สำหรับ Cloud Functions ที่เขียนด้วย Python มี 2 วิธี ได้แก่ การใช้ไฟล์ requirements.txt ของเครื่องมือจัดการแพ็กเกจ pip หรือการจัดแพ็กเกจทรัพยากร Dependency ในเครื่องควบคู่ไปกับฟังก์ชันของคุณ

ไม่รองรับข้อกำหนดเฉพาะของทรัพยากร Dependency ที่ใช้มาตรฐาน Pipfile/Pipfile.lock โปรเจ็กต์ของคุณไม่ควรมีไฟล์เหล่านี้

การระบุทรัพยากร Dependency ด้วย pip

ระบบจะจัดการทรัพยากร Dependency ใน Python ด้วย pip และแสดงในไฟล์ข้อมูลเมตาที่ชื่อว่า requirements.txt ไฟล์นี้ต้องอยู่ในไดเรกทอรีเดียวกับไฟล์ main.py ที่มีโค้ดฟังก์ชัน

เมื่อคุณทำให้ฟังก์ชันใช้งานได้หรือทำให้ใช้งานได้อีกครั้ง Cloud Functions จะใช้ pip เพื่อดาวน์โหลดและติดตั้งทรัพยากร Dependency เวอร์ชันล่าสุดตามที่ประกาศไว้ในไฟล์ requirements.txt ไฟล์ requirements.txt มี 1 บรรทัดต่อแพ็กเกจ แต่ละบรรทัดประกอบด้วยชื่อแพ็กเกจ และเวอร์ชันที่ขอ (ไม่บังคับ) ดูรายละเอียดเพิ่มเติมได้ที่ข้อมูลอ้างอิง requirements.txt

หากต้องการป้องกันไม่ให้บิลด์ได้รับผลกระทบจากการเปลี่ยนแปลงเวอร์ชันของทรัพยากร Dependency ให้พิจารณาปักหมุดแพ็กเกจทรัพยากร Dependency ไว้ที่เวอร์ชันที่เฉพาะเจาะจง

ต่อไปนี้เป็นตัวอย่างไฟล์ requirements.txt

functions-framework
requests==2.20.0
numpy

การแพ็กทรัพยากร Dependency ในเครื่อง

นอกจากนี้ คุณยังจัดแพ็กเกจและติดตั้งใช้งานทรัพยากร Dependency ควบคู่ไปกับฟังก์ชันได้ด้วย วิธีนี้มีประโยชน์หากทรัพยากร Dependency ไม่พร้อมใช้งานผ่านเครื่องมือจัดการแพ็กเกจ 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