ارتقا دادن از namespaced API به برنامه پیمانه‌ای

برنامه‌هایی که از هر میانای برنامه‌سازی کاربردی وب Firebase با فضای نام استفاده می‌کنند، از کتابخانه‌های compat تا نسخه ۸ یا قدیمی‌تر، باید بااستفاده از دستورالعمل‌های این راهنما به میانای برنامه‌سازی کاربردی مدولار منتقل شوند.

این راهنما فرض می‌کند که شما با namespaced API آشنا هستید و از یک بسته‌بندی‌کننده ماژول مانند webpack یا Rollup برای ارتقا و توسعه مداوم برنامه مدولار استفاده خواهید کرد.

اکیداً توصیه می‌شود که از بسته‌بندی‌کننده ماژول در محیط توسعه نرم‌افزارتان استفاده کنید. اگر از یکی از آن‌ها استفاده نکنید، نمی‌توانید از مزایای اصلی API پیمانه‌ای در کاهش اندازه برنامه بهره‌مند شوید. برای نصب کیت توسعه نرم‌افزار به npm یا yarn نیاز دارید.

مراحل ارتقا در این راهنما براساس یک برنامه وب فرضی است که از کیت‌های توسعه نرم‌افزار Authentication و Cloud Firestore استفاده می‌کند. با کار کردن روی مثال‌ها، می‌توانید بر مفاهیم و مراحل عملی موردنیاز برای ارتقای همه کیت‌های توسعه نرم‌افزار وب Firebase پشتیبانی‌شده مسلط شوید.

درباره کتابخانه‌های دارای فضای نام (compat)

دو نوع کتابخانه برای کیت توسعه نرم‌افزار وب Firebase دردسترس است:

  • مدولار - سطح جدید میانای برنامه‌سازی کاربردی که برای تسهیل حذف کد بلااستفاده طراحی شده است تا برنامه وب شما را تا حد امکان کوچک و سریع کند.
  • Namespaced (compat) - یک سطح API آشنا که کاملاً با نسخه‌های قبلی کیت توسعه نرم‌افزار سازگار است و به شما امکان می‌دهد بدون تغییر دادن همه کدهای Firebase به‌طور هم‌زمان، ارتقا دهید. کتابخانه‌های Compat نسبت‌به همتایان فضای نامی خود مزایای اندازه یا عملکردی کمی دارند یا اصلاً ندارند.

این راهنما فرض می‌کند که شما از کتابخانه‌های سازگاری برای تسهیل ارتقا استفاده خواهید کرد. این کتابخانه‌ها به شما امکان می‌دهند به استفاده از کد فضای نام درکنار کد بازسازی‌شده برای modular API ادامه دهید. این یعنی می‌توانید درحین انجام فرایند ارتقا، برنامه‌تان را راحت‌تر کامپایل و اشکال‌زدایی کنید.

برای برنامه‌هایی که مواجهه بسیار کمی با کیت توسعه نرم‌افزار وب Firebase دارند—برای مثال، برنامه‌ای که فقط یک فراخوانی ساده به میاناهای برنامه‌سازی کاربردی Authentication انجام می‌دهد—ممکن است بازسازی کد قدیمی فضای نام بدون استفاده از کتابخانه‌های سازگاری عملی باشد. اگر درحال ارتقا دادن چنین برنامه‌ای هستید، می‌توانید دستورالعمل‌های این راهنما را برای «میانای برنامه‌سازی کاربردی پیمانه‌ای» بدون استفاده از کتابخانه‌های سازگاری دنبال کنید.

درباره فرایند ارتقا دادن

هر مرحله از فرایند ارتقا محدود شده است تا بتوانید ویرایش منبع را برای برنامه‌تان تمام کنید و سپس آن را بدون خرابی کامپایل و اجرا کنید. به‌طور خلاصه، برای ارتقا دادن برنامه باید این کارها را انجام دهید:

  1. کتابخانه‌های مدولار و کتابخانه‌های سازگار را به برنامه‌تان اضافه کنید.
  2. عبارت‌های وارد کردن را در کدتان به compat به‌روز کنید.
  3. کد را برای یک محصول (مثلاً Authentication) به سبک پیمانه‌ای بازسازی کنید.
  4. اختیاری: در این مرحله، کتابخانه سازگاری Authentication و کد سازگاری Authentication را بردارید تا قبل‌از ادامه دادن، از مزیت اندازه برنامه برای Authentication بهره‌مند شوید.
  5. بازسازی کردن توابع برای هر محصول (برای مثال، Cloud Firestore، FCM، و غیره) به سبک مدولار، کامپایل کردن و آزمایش کردن تا زمانی که همه بخش‌ها تکمیل شوند.
  6. کد مقداردهی اولیه را به سبک واحدی به‌روز کنید.
  7. همه عبارت‌های سازگاری و کدهای سازگاری باقی‌مانده را از برنامه‌تان بردارید.

دریافت جدیدترین نسخه کیت توسعه نرم‌افزار

برای شروع، کتابخانه‌های پیمانه‌ای و کتابخانه‌های سازگار را بااستفاده از npm دریافت کنید:

npm i firebase@13.2.0

# OR

yarn add firebase@13.2.0

به‌روزرسانی واردات به compat

برای اینکه کدتان پس‌از به‌روزرسانی وابستگی‌ها همچنان کار کند، عبارت‌های وارد کردن را تغییر دهید تا از نسخه «سازگار» هر وارد کردن استفاده شود. برای مثال:

قبل‌از: نسخه ۸ یا قدیمی‌تر

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/firestore';

بعداز: compat

// compat packages are API compatible with namespaced code
import firebase from 'firebase/compat/app';
import 'firebase/compat/auth';
import 'firebase/compat/firestore';

بازسازی کد به سبک پیمانه‌ای

درحالی‌که میاناهای برنامه‌سازی کاربردی فضای نامی براساس الگوی سرویس و فضای نامی زنجیره‌ای نقطه‌ای هستند، رویکرد مدولار به این معنی است که کد شما عمدتاً حول توابع سازماندهی خواهد شد. در میانای برنامه‌سازی کاربردی پیمانه‌ای، بسته firebase/app و بسته‌های دیگر صادر کردن جامعی را که حاوی همه روش‌های بسته باشد برنمی‌گردانند. درعوض، بسته‌ها توابع تکی را صادر می‌کنند.

در میانای برنامه‌سازی کاربردی پیمانه‌ای، سرویس‌ها به‌عنوان اولین شناسه ارسال می‌شوند و سپس تابع از جزئیات سرویس برای انجام بقیه کارها استفاده می‌کند. بیایید نحوه عملکرد این موضوع را در دو مثال بررسی کنیم که فراخوانی‌های میاناهای برنامه‌سازی کاربردی Authentication و Cloud Firestore را بازسازی کد می‌کنند.

مثال ۱: بازسازی کد تابع Authentication

قبل: compat

کد compat با کد namespaced یکسان است، اما واردات تغییر کرده است.

import firebase from "firebase/compat/app";
import "firebase/compat/auth";

const auth = firebase.auth();
auth.onAuthStateChanged(user => { 
  // Check for user status
});

بعد: مدولار

تابع getAuth، firebaseApp را به‌عنوان اولین پارامتر خود می‌گیرد. تابع onAuthStateChanged از نمونه auth زنجیره‌ای نیست، همان‌طور که در namespaced API خواهد بود؛ درعوض، تابع آزادی است که auth را به‌عنوان اولین پارامتر خود می‌گیرد.

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => {
  // Check for user status
});

به‌روزرسانی مدیریت روش احراز هویت getRedirectResult

میانای برنامه‌سازی کاربردی پیمانه‌ای تغییری اساسی در getRedirectResult ایجاد می‌کند. وقتی هیچ عملیات هدایت مجددی فراخوانی نشود، modular API برخلاف namespaced API که UserCredential را با کاربر null برمی‌گرداند، null را برمی‌گرداند.

قبل: compat

const result = await auth.getRedirectResult()
if (result.user === null && result.credential === null) {
  return null;
}
return result;

بعد: مدولار

const result = await getRedirectResult(auth);
// Provider of the access token could be Facebook, Github, etc.
if (result === null || provider.credentialFromResult(result) === null) {
  return null;
}
return result;

مثال ۲: بازسازی کردن کد تابع Cloud Firestore

قبل: compat

import "firebase/compat/firestore"

const db = firebase.firestore();
db.collection("cities").where("capital", "==", true)
    .get()
    .then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
            // doc.data() is never undefined for query doc snapshots
            console.log(doc.id, " => ", doc.data());
        });
    })
    .catch((error) => {
        console.log("Error getting documents: ", error);
    });

بعد: مدولار

تابع getFirestore، firebaseApp را به‌عنوان اولین پارامتر خود می‌گیرد که در مثال قبلی از initializeApp برگردانده شده بود. ببینید چطور کد تشکیل پُرسمان در API مدولار بسیار متفاوت است؛ هیچ زنجیره‌ای وجود ندارد و روش‌هایی مانند query یا where اکنون به‌عنوان توابع آزاد نمایش داده می‌شوند.

import { getFirestore, collection, query, where, getDocs } from "firebase/firestore";

const db = getFirestore(firebaseApp);

const q = query(collection(db, "cities"), where("capital", "==", true));

const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc) => {
  // doc.data() is never undefined for query doc snapshots
  console.log(doc.id, " => ", doc.data());
});

به‌روزرسانی ارجاع‌ها به Firestore DocumentSnapshot.exists

‫modular API تغییر ناسازگاری را معرفی می‌کند که در آن ویژگی firestore.DocumentSnapshot.exists به روش تغییر کرده است. عملکرد اساساً یکسان است (آزمایش اینکه آیا سند وجود دارد یا نه) اما باید کدتان را بازسازی کنید تا از روش جدیدتر استفاده کند، همان‌طور که نشان داده شده است:

Before:compat

if (snapshot.exists) {
  console.log("the document exists");
}

بعد: مدولار

if (snapshot.exists()) {
  console.log("the document exists");
}

مثال ۳: ترکیب سبک‌های کد مدولار و فضانام‌دار

استفاده از کتابخانه‌های compat درطول ارتقا به شما امکان می‌دهد همچنان از کد فضای نام درکنار کد بازسازی‌شده برای modular API استفاده کنید. این یعنی می‌توانید کد فضای نام موجود را برای Cloud Firestore نگه دارید و درعین‌حال Authentication یا کد کیت توسعه نرم‌افزار Firebase دیگر را به سبک پیمانه‌ای بازسازی کنید و همچنان برنامه‌تان را با هر دو سبک کد با موفقیت کامپایل کنید. این موضوع برای کد API مدولار و فضای نامی درون محصولی مانند Cloud Firestore نیز صادق است؛ سبک‌های کد جدید و قدیمی می‌توانند هم‌زیستی داشته باشند، به‌شرطی که بسته‌های سازگاری را وارد کنید:

import firebase from 'firebase/compat/app';
import 'firebase/compat/firestore';
import { getDoc } from 'firebase/firestore'

const docRef = firebase.firestore().doc();
getDoc(docRef);

به‌خاطر داشته باشید که اگرچه برنامه‌تان کامپایل خواهد شد، اما تا زمانی که عبارات و کد compat را به‌طور کامل از برنامه‌تان حذف نکنید، از مزایای اندازه برنامه کد مدولار بهره‌مند نخواهید شد.

به‌روزرسانی کد مقداردهی اولیه

کد مقداردهی اولیه برنامه‌تان را به‌روز کنید تا از نحو پیمانه‌ای استفاده کند. مهم است که این کد را پس‌از تکمیل بازسازی کد در برنامه‌تان به‌روز کنید؛ زیرا firebase.initializeApp() وضعیت سراسری را برای هر دو API سازگار و مدولار مقداردهی اولیه می‌کند، درحالی‌که تابع مدولار initializeApp() فقط وضعیت را برای مدولار مقداردهی اولیه می‌کند.

قبل: compat

import firebase from "firebase/compat/app"

firebase.initializeApp({ /* config */ });

بعد: مدولار

import { initializeApp } from "firebase/app"

const firebaseApp = initializeApp({ /* config */ });

برداشتن کد سازگاری

برای بهره‌مندی از مزایای اندازه API واحد، درنهایت باید همه فراخوانی‌ها را به سبک واحد نشان‌داده‌شده در بالا تبدیل کنید و همه عبارت‌های import "firebase/compat/* را از کدتان بردارید. وقتی کارتان تمام شد، دیگر نباید هیچ ارجاعی به فضای نام جهانی firebase.* یا هر کد دیگری در سبک namespaced API وجود داشته باشد.

استفاده از کتابخانه compat از پنجره

‫modular API برای کار با ماژول‌ها بهینه‌سازی شده است، نه شیء window مرورگر. نسخه‌های قبلی کتابخانه امکان بار کردن و مدیریت Firebase را بااستفاده از جای‌نام window.firebase فراهم می‌کرد. این روش برای آینده توصیه نمی‌شود زیرا امکان حذف کد استفاده‌نشده را فراهم نمی‌کند. بااین‌حال، نسخه سازگار کیت توسعه نرم‌افزار جاوا اسکریپت با window برای توسعه‌دهندگانی که ترجیح می‌دهند فوراً مسیر ارتقای مدولار را شروع نکنند کار می‌کند.

<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/13.2.0/firebase-auth-compat.js"></script>
<script>
   const firebaseApp = firebase.initializeApp({ /* Firebase config */ });
   const db = firebaseApp.firestore();
   const auth = firebaseApp.auth();
</script>

کتابخانه سازگاری از کد مدولار در پشت صحنه استفاده می‌کند و آن را با همان میانای برنامه‌سازی کاربردی به‌عنوان میانای برنامه‌سازی کاربردی فضای نامی ارائه می‌دهد؛ این یعنی می‌توانید برای جزئیات به مرجع میانای برنامه‌سازی کاربردی فضای نامی و قطعه کدهای فضای نامی مراجعه کنید. این روش برای استفاده طولانی‌مدت توصیه نمی‌شود، اما به‌عنوان شروعی برای ارتقا به کتابخانه کاملاً مدولار مناسب است.

مزایا و محدودیت‌های کیت توسعه نرم‌افزار واحد

کیت توسعه نرم‌افزار کاملاً مدولارشده این مزایا را نسبت‌به نسخه‌های قبلی دارد:

  • کیت توسعه نرم‌افزار مدولار باعث کاهش چشمگیر اندازه برنامه می‌شود. این کیت توسعه نرم‌افزار از قالب مدرن JavaScript Module استفاده می‌کند که امکان استفاده از روش‌های «tree shaking» را فراهم می‌کند. در این روش‌ها، فقط مصنوعاتی را که برنامه‌تان نیاز دارد وارد می‌کنید. بسته به برنامه شما، حذف کد بلااستفاده با کیت توسعه نرم‌افزار پیمانه‌ای می‌تواند منجر به ۸۰٪ کیلوبایت کمتر نسبت به برنامه مشابهی شود که بااستفاده از namespaced API ساخته شده است.
  • کیت توسعه نرم‌افزار پیمانه‌ای همچنان از توسعه ویژگی‌های درحال انجام بهره‌مند خواهد شد، درحالی‌که namespaced API این‌گونه نخواهد بود.