อัปเกรดจาก Namespaced API เป็น Modular API

แอปที่ใช้ Namespace ของ Firebase Web API อยู่ในขณะนี้จากไลบรารี compat กลับไปใช้เวอร์ชัน 8 หรือเวอร์ชันก่อนหน้า ย้ายข้อมูลไปยัง API โมดูล โดยใช้วิธีการในคู่มือนี้

คู่มือนี้จะถือว่า ที่คุณคุ้นเคยกับ Namespaced API และจะได้รับประโยชน์จาก Bundler ของโมดูล เช่น webpack หรือ ภาพรวมสำหรับการอัปเกรดและ การพัฒนาแอปแบบแยกส่วนอย่างต่อเนื่อง

การใช้ Module Bundler ในสภาพแวดล้อมการพัฒนามีความสำคัญอย่างยิ่ง แนะนำ หากคุณไม่ใช้โปรไฟล์ คุณจะไม่สามารถใช้ประโยชน์จาก ข้อดีหลักๆ ของ Modular API ในเรื่องขนาดแอปที่ลดขนาดลง คุณจะต้องมี npm หรือ yarn เพื่อติดตั้ง SDK

ขั้นตอนการอัปเกรดในคู่มือนี้จะขึ้นอยู่กับเว็บแอปสมมติที่ ใช้ SDK Authentication และ Cloud Firestore ในตัวอย่างนี้ สามารถทำความเข้าใจแนวคิดและขั้นตอนที่นำไปปฏิบัติได้จริงที่จำเป็นสำหรับการอัปเกรดทั้งหมดที่รองรับ Firebase Web SDK

เกี่ยวกับไลบรารีที่ใช้เนมสเปซ (compat)

Firebase Web SDK มีไลบรารีอยู่ 2 ประเภท ได้แก่

  • โมดูลาร์ - แพลตฟอร์ม API ใหม่ที่ออกแบบมาเพื่ออำนวยความสะดวกในการเขย่าต้นไม้ (นำโค้ดที่ไม่ได้ใช้งานออก) ไปยัง ทำให้เว็บแอปมีขนาดเล็กและเร็วที่สุด
  • เนมสเปซ (compat) - แพลตฟอร์ม API ที่คุ้นเคยซึ่ง ที่ใช้งานร่วมกันได้กับ เวอร์ชันก่อนหน้าของ SDK ที่ช่วยให้คุณอัปเกรด ได้โดยไม่ต้องเปลี่ยน ของโค้ด Firebase ได้พร้อมกัน ไลบรารี Compat มี ไม่มีขนาดหรือประสิทธิภาพ ข้อได้เปรียบเหนือคู่ที่ใช้เนมสเปซ

คู่มือนี้จะถือว่าคุณจะใช้ประโยชน์จากการทำงานร่วมกับ เพื่ออำนวยความสะดวกในการอัปเกรด ไลบรารีเหล่านี้ช่วยให้คุณดำเนินการต่อ โดยใช้โค้ด Namespace ควบคู่ไปกับโค้ดที่เปลี่ยนโครงสร้างภายในโค้ดสำหรับ Modular API ซึ่งหมายความว่าคุณ สามารถคอมไพล์และแก้ไขข้อบกพร่องของแอปได้ง่ายขึ้นในขณะที่ดำเนินการอัปเกรด ขั้นตอนได้

สำหรับแอปที่มีจำนวนผู้ที่เห็น Firebase Web SDK น้อยมาก เช่น แอปที่เรียกง่ายๆ ไปยัง Authentication API อาจเป็น มีประโยชน์ในการรีแฟคเตอร์โค้ด Namespace เก่าโดยไม่ต้องใช้ไลบรารี Compat หากคุณกำลังอัปเกรดแอปเช่นนี้ คุณสามารถทำตามวิธีการในคู่มือนี้ สำหรับ "modular API" โดยไม่ต้องใช้ไลบรารีที่ใช้ร่วมกันได้

เกี่ยวกับกระบวนการอัปเกรด

กระบวนการอัปเกรดแต่ละขั้นตอนจะถูกกำหนดขอบเขตเพื่อให้คุณสามารถแก้ไข สำหรับแอปของคุณ จากนั้นคอมไพล์และเรียกใช้โดยไม่เกิดการหยุดชะงัก กล่าวโดยสรุป นี่คือสิ่งที่คุณจะทำเพื่ออัปเกรดแอป

  1. เพิ่มไลบรารีโมดูลและไลบรารีที่ใช้ร่วมกันในแอป
  2. อัปเดตคำสั่งการนำเข้าในโค้ดเพื่อจับคู่กับ
  3. เปลี่ยนโครงสร้างโค้ดสำหรับผลิตภัณฑ์รายการเดียว (เช่น Authentication) เป็น รูปแบบโมดูล
  4. ไม่บังคับ: ณ จุดนี้ ให้นำไลบรารีความเข้ากันได้ Authentication และโค้ดการจับคู่ออก สำหรับ Authentication เพื่อ ตระหนักถึงประโยชน์ของขนาดแอปสำหรับ Authentication ก่อนดำเนินการต่อ
  5. เปลี่ยนโครงสร้างภายในฟังก์ชันของแต่ละผลิตภัณฑ์ (เช่น Cloud Firestore, FCM ฯลฯ) ในรูปแบบโมดูล การคอมไพล์ และ ทดสอบจนกว่าทุกด้านจะเสร็จสมบูรณ์
  6. อัปเดตโค้ดการเริ่มต้นให้อยู่ในรูปแบบโมดูล
  7. นำข้อความการจับคู่และรหัสการจับคู่ที่เหลืออยู่ทั้งหมดออกจาก แอปของคุณ

ดาวน์โหลด SDK เวอร์ชันล่าสุด

ในการเริ่มต้นใช้งาน ให้เรียกไลบรารีโมดูลและไลบรารีที่ใช้ร่วมกันโดยใช้ npm ดังนี้

npm i [email protected]

# OR

yarn add [email protected]

อัปเดตการนำเข้าไปยังการจับคู่

เพื่อให้โค้ดทำงานได้อย่างต่อเนื่องหลังจากอัปเดตทรัพยากร Dependency เปลี่ยนข้อความการนำเข้าไปใช้ "การจับคู่" เวอร์ชันของการนำเข้าแต่ละรายการ เช่น

ก่อน: เวอร์ชัน 8 หรือเวอร์ชันก่อนหน้า

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

หลัง: การจับคู่

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

เปลี่ยนโครงสร้างภายในรูปแบบโมดูล

แม้ว่า API ที่ใช้เนมสเปซนั้นจะอิงตามเนมสเปซและบริการที่ผูกกันแบบจุด รูปแบบ วิธีการแบบแยกส่วนหมายความว่าโค้ดของคุณจะได้รับการจัดระเบียบ โดยพื้นฐานแล้วจะอยู่ที่ฟังก์ชัน ใน API แบบแยกส่วน แพ็กเกจ firebase/app และ แพ็กเกจอื่นจะไม่ส่งคืนการส่งออกที่ครอบคลุมที่มีข้อมูล จากแพ็กเกจได้ แต่แพ็กเกจจะส่งออกฟังก์ชันแต่ละรายการแทน

ใน API แบบแยกส่วน ระบบจะส่งบริการเป็นอาร์กิวเมนต์แรก แล้วประมวลผลฟังก์ชัน จะใช้รายละเอียดของบริการเพื่อดำเนินการในส่วนที่เหลือ มาดูวิธีการทำงานของเครื่องมือนี้ใน ตัวอย่าง 2 รายการที่เปลี่ยนโครงสร้างการเรียกไปยัง API Authentication และ Cloud Firestore

ตัวอย่างที่ 1: การเปลี่ยนโครงสร้างภายในฟังก์ชัน Authentication

ก่อน: ความเข้ากันได้

รหัสการจับคู่จะเหมือนกับรหัสเนมสเปซ แต่ มีการเปลี่ยนแปลง

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

Modular API มีการเปลี่ยนแปลงที่ส่งผลกับส่วนอื่นในระบบใน getRedirectResult เมื่อไม่มีการเรียกใช้การดำเนินการเปลี่ยนเส้นทาง API โมดูลนี้จะแสดงผล null แทนที่จะเป็น Namespaced API ซึ่งแสดงผล UserCredential ที่มีผู้ใช้ null

ก่อน: ความเข้ากันได้

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;

ตัวอย่างที่ 2: การเปลี่ยนโครงสร้างภายในฟังก์ชัน Cloud Firestore

ก่อน: ความเข้ากันได้

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 ถูกเปลี่ยนเป็น เมธอด แล้ว ฟังก์ชันการทำงานนั้นโดยพื้นฐานแล้วเหมือนกัน (การทดสอบว่ามีเอกสารอยู่หรือไม่) แต่คุณต้องเปลี่ยนโครงสร้างภายในโค้ดเพื่อใช้วิธีการที่ใหม่กว่าดังที่ปรากฏ

ก่อน:ความเข้ากันได้

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

หลัง: โมดูล

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

ตัวอย่างที่ 3: การรวมรูปแบบโค้ดเนมสเปซและโมดูลาร์

การใช้ไลบรารีความเข้ากันได้ระหว่างการอัปเกรดจะช่วยให้คุณใช้เนมสเปซต่อไปได้ โค้ดควบคู่กับโค้ดที่เปลี่ยนโครงสร้างภายในโค้ดสำหรับ Modular API ซึ่งหมายความว่าคุณสามารถเก็บ โค้ดเนมสเปซที่มีอยู่สำหรับ Cloud Firestore ขณะที่คุณเปลี่ยนโครงสร้างภายในโค้ด Authentication หรือโค้ด Firebase SDK อื่นๆ เพื่อ รูปแบบโมดูลยังสามารถคอมไพล์แอปด้วยโค้ดทั้ง 2 แบบได้ รูปแบบ เช่นเดียวกันกับโค้ด API แบบ Namespace และ Modular ภายในผลิตภัณฑ์ เช่น ในฐานะ Cloud Firestore; รูปแบบโค้ดทั้งเก่าและใหม่จะสามารถอยู่ร่วมกันได้ ตราบใดที่คุณยัง การนำเข้าแพ็กเกจที่เข้ากันได้:

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

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

โปรดทราบว่าแม้แอปของคุณจะคอมไพล์ แต่คุณจะไม่ได้รับขนาดแอป ประโยชน์ของโค้ดโมดูล จนกว่าคุณจะนำคำสั่งที่ใช้ร่วมกันออกทั้งหมด จากแอปของคุณ

อัปเดตโค้ดการเริ่มต้น

อัปเดตโค้ดการเริ่มต้นของแอปให้ใช้ไวยากรณ์โมดูล ใช่เลย การอัปเดตโค้ดนี้หลังจาก ที่คุณเปลี่ยนโครงสร้างภายในโค้ดทั้งหมด โค้ดในแอปของคุณ เนื่องจาก firebase.initializeApp() เริ่มต้นการทำงานทั่วโลก สำหรับทั้ง API ที่ใช้ร่วมกันและโมดูลาร์ ในขณะที่โมดูล ฟังก์ชัน initializeApp() จะเริ่มต้นเฉพาะสถานะสำหรับโมดูล

ก่อน: ความเข้ากันได้

import firebase from "firebase/compat/app"

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

หลัง: โมดูล

import { initializeApp } from "firebase/app"

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

นำรหัสความเข้ากันได้ออก

เพื่อให้ทราบถึงประโยชน์ด้านขนาดของ API โมดูล คุณควรในท้ายที่สุด จะแปลงคำขอทั้งหมดเป็นรูปแบบโมดูลที่แสดงด้านบน แล้วนำ import "firebase/compat/* คำสั่งจากรหัสของคุณ เมื่อเสร็จแล้ว ไม่ควรมีการอ้างอิงไปยังเนมสเปซส่วนกลางหรืออื่นๆ ของ firebase.* ในรูปแบบ API ที่ใช้เนมสเปซ

การใช้ไลบรารีการทำงานร่วมกันจากหน้าต่าง

Modular API ได้รับการเพิ่มประสิทธิภาพให้ทำงานกับโมดูล แทนที่จะเป็นเบราว์เซอร์ ออบเจ็กต์ window รายการ เวอร์ชันก่อนหน้าของไลบรารีช่วยให้สามารถโหลดและ ของ Firebase โดยใช้เนมสเปซ window.firebase ไม่ใช่ ขอแนะนำให้ดำเนินการตั้งแต่นี้เป็นต้นไป เนื่องจากจะไม่อนุญาตให้ลบโค้ดที่ไม่ได้ใช้งาน แต่ JavaScript SDK เวอร์ชันที่เข้ากันได้จะทำงานกับ window สำหรับนักพัฒนาซอฟต์แวร์ที่ไม่ต้องการเริ่มเส้นทางการอัปเกรดแบบแยกส่วนทันที

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

ไลบรารีความเข้ากันได้ใช้โค้ดโมดูลภายในขั้นสูงและ ให้ API เดียวกันกับ API ที่ใช้เนมสเปซ ซึ่งหมายความว่าคุณสามารถ โปรดดูการอ้างอิง Namespaced API และข้อมูลโค้ดที่ใช้เนมสเปซเพื่อดูรายละเอียด วิธีนี้ไม่ได้ แนะนำให้ใช้ในระยะยาว แต่เป็นจุดเริ่มต้นในการอัปเกรดเป็นโมดูลทั้งหมด ไลบรารี

ประโยชน์และข้อจำกัดของ SDK แบบแยกส่วน

SDK แบบแยกส่วนทั้งหมดมีข้อดีกว่าเวอร์ชันก่อนหน้าดังต่อไปนี้

  • SDK แบบแยกส่วนช่วยให้แอปมีขนาดเล็กลงอย่างมาก นำ JavaScript สมัยใหม่ไปใช้ รูปแบบโมดูล ทำให้เกิด "การสั่นสะเทือนของต้นไม้" แนวทางปฏิบัติที่คุณนำเข้า เฉพาะอาร์ติแฟกต์ที่แอปต้องการเท่านั้น ซึ่งขึ้นอยู่กับแอปของคุณ การสั่นสะเทือนจากต้นไม้ด้วย SDK แบบแยกส่วน อาจส่งผลให้มีกิโลไบต์น้อยกว่า แอปที่เทียบเคียงกันได้ซึ่งสร้างขึ้นโดยใช้ Namespaced API
  • SDK แบบแยกส่วนจะยังคงได้รับประโยชน์จากการพัฒนาฟีเจอร์อย่างต่อเนื่อง แต่ API ของเนมสเปซจะไม่เกิดขึ้น