Nâng cấp từ API được đặt tên lên API mô-đun

Các ứng dụng hiện đang sử dụng bất kỳ API Web Firebase có không gian tên nào, từ thư viện compat từ phiên bản 8 trở về trước, nên cân nhắc việc chuyển sang API mô-đun bằng cách sử dụng hướng dẫn trong hướng dẫn này.

Hướng dẫn này giả định rằng bạn đã quen thuộc với API không gian tên và bạn sẽ tận dụng gói mô-đun như webpack hoặc Rollup để nâng cấp và phát triển ứng dụng mô-đun liên tục.

Bạn nên sử dụng bộ đóng gói mô-đun trong môi trường phát triển của mình. Nếu không sử dụng API mô-đun, bạn sẽ không thể tận dụng các lợi ích chính của API mô-đun trong việc giảm kích thước ứng dụng. Bạn sẽ cần npm hoặc sợi để cài đặt SDK.

Các bước nâng cấp trong hướng dẫn này sẽ dựa trên một ứng dụng web tưởng tượng sử dụng SDK xác thực và Cloud Firestore SDK. Bằng cách xem qua các ví dụ, bạn có thể nắm vững các khái niệm và các bước thực tế cần thiết để nâng cấp tất cả SDK Web Firebase được hỗ trợ.

Giới thiệu về các thư viện không gian tên ( compat )

Có hai loại thư viện có sẵn cho SDK Web Firebase:

  • Mô-đun - một bề mặt API mới được thiết kế để tạo điều kiện thuận lợi cho việc rung cây (loại bỏ mã không sử dụng) nhằm làm cho ứng dụng web của bạn nhỏ và nhanh nhất có thể.
  • Không gian tên ( compat ) - một bề mặt API quen thuộc hoàn toàn tương thích với các phiên bản SDK cũ hơn, cho phép bạn nâng cấp mà không cần thay đổi tất cả mã Firebase cùng một lúc. Các thư viện tương thích có rất ít hoặc không có lợi thế về kích thước hoặc hiệu suất so với các đối tác được đặt tên theo không gian của chúng.

Hướng dẫn này giả định rằng bạn sẽ tận dụng các thư viện tương thích để hỗ trợ việc nâng cấp của mình. Các thư viện này cho phép bạn tiếp tục sử dụng mã được đặt tên cùng với mã được tái cấu trúc cho API mô-đun. Điều này có nghĩa là bạn có thể biên dịch và gỡ lỗi ứng dụng của mình dễ dàng hơn khi thực hiện quá trình nâng cấp.

Đối với các ứng dụng có mức độ tiếp xúc rất nhỏ với SDK Web Firebase—ví dụ: một ứng dụng chỉ thực hiện lệnh gọi đơn giản tới API xác thực—việc cấu trúc lại mã không gian tên cũ hơn mà không cần sử dụng thư viện tương thích có thể là thực tế. Nếu đang nâng cấp một ứng dụng như vậy, bạn có thể làm theo hướng dẫn trong hướng dẫn này dành cho "API mô-đun" mà không cần sử dụng thư viện tương thích.

Về quá trình nâng cấp

Mỗi bước của quá trình nâng cấp đều có phạm vi để bạn có thể hoàn tất việc chỉnh sửa nguồn cho ứng dụng của mình, sau đó biên dịch và chạy ứng dụng đó mà không bị hỏng. Tóm lại, đây là những gì bạn sẽ làm để nâng cấp ứng dụng:

  1. Thêm thư viện mô-đun và thư viện tương thích vào ứng dụng của bạn.
  2. Cập nhật các câu lệnh nhập trong mã của bạn thành tương thích.
  3. Tái cấu trúc mã cho một sản phẩm (ví dụ: Xác thực) thành kiểu mô-đun.
  4. Tùy chọn: tại thời điểm này, hãy xóa thư viện tương thích Xác thực và mã tương thích cho Xác thực để nhận ra lợi ích về kích thước ứng dụng cho Xác thực trước khi tiếp tục.
  5. Chức năng tái cấu trúc cho từng sản phẩm (ví dụ: Cloud Firestore, FCM, v.v.) theo kiểu mô-đun, biên dịch và thử nghiệm cho đến khi hoàn thiện tất cả các khu vực.
  6. Cập nhật mã khởi tạo theo kiểu mô-đun.
  7. Xóa tất cả các câu lệnh tương thích và mã tương thích còn lại khỏi ứng dụng của bạn.

Tải phiên bản SDK mới nhất

Để bắt đầu, hãy tải các thư viện mô-đun và thư viện tương thích bằng npm:

npm i firebase@10.9.0

# OR

yarn add firebase@10.9.0

Cập nhật nhập vào tương thích

Để giữ cho mã của bạn hoạt động sau khi cập nhật các phần phụ thuộc, hãy thay đổi câu lệnh nhập để sử dụng phiên bản "tương thích" của mỗi lần nhập. Ví dụ:

Trước: phiên bản 8 trở về trước

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

Sau: tương thích

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

Tái cấu trúc theo phong cách mô-đun

Mặc dù các API được đặt tên dựa trên không gian tên và mẫu dịch vụ theo chuỗi dấu chấm, nhưng cách tiếp cận mô-đun có nghĩa là mã của bạn sẽ được tổ chức chủ yếu xung quanh các hàm . Trong API mô-đun, gói firebase/app và các gói khác không trả về bản xuất toàn diện có chứa tất cả các phương thức từ gói. Thay vào đó, các gói xuất các hàm riêng lẻ.

Trong API mô-đun, các dịch vụ được chuyển làm đối số đầu tiên và sau đó hàm sẽ sử dụng các chi tiết của dịch vụ để thực hiện phần còn lại. Hãy xem xét cách thức hoạt động của tính năng này trong hai ví dụ tái cấu trúc lệnh gọi tới API Xác thực và API Cloud Firestore.

Ví dụ 1: tái cấu trúc chức năng Xác thực

Trước: tương thích

Mã tương thích giống hệt với mã được đặt tên, nhưng quá trình nhập đã thay đổi.

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

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

Sau: mô-đun

Hàm getAuth lấy firebaseApp làm tham số đầu tiên. Hàm onAuthStateChanged không bị xích khỏi phiên bản auth như trong API không gian tên; thay vào đó, đây là một hàm miễn phí lấy auth làm tham số đầu tiên.

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

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

Cập nhật xử lý phương thức Auth getRedirectResult

API mô-đun giới thiệu một thay đổi đột phá trong getRedirectResult . Khi không có thao tác chuyển hướng nào được gọi, API mô-đun trả về null thay vì API được đặt tên trả về UserCredential với người dùng null .

Trước: tương thích

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

Sau: mô-đun

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;

Ví dụ 2: tái cấu trúc hàm Cloud Firestore

Trước: tương thích

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);
    });

Sau: mô-đun

Hàm getFirestore lấy firebaseApp làm tham số đầu tiên, tham số này được trả về từ initializeApp trong ví dụ trước. Lưu ý rằng mã để tạo một truy vấn rất khác trong API mô-đun; không có chuỗi và các phương thức như query hoặc where hiện được hiển thị dưới dạng các hàm miễn phí.

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());
});

Cập nhật các tham chiếu đến Firestore DocumentSnapshot.exists

API mô-đun đưa ra một thay đổi đột phá trong đó thuộc tính firestore.DocumentSnapshot.exists đã được thay đổi thành một phương thức . Chức năng về cơ bản là giống nhau (kiểm tra xem tài liệu có tồn tại hay không) nhưng bạn phải cấu trúc lại mã của mình để sử dụng phương thức mới hơn như được hiển thị:

Trước: tương thích

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

Sau: mô-đun

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

Ví dụ 3: kết hợp các kiểu mã không gian tên và mô-đun

Việc sử dụng thư viện tương thích trong quá trình nâng cấp cho phép bạn tiếp tục sử dụng mã không gian tên cùng với mã được tái cấu trúc cho API mô-đun. Điều này có nghĩa là bạn có thể giữ mã không gian tên hiện có cho Cloud Firestore trong khi cấu trúc lại Xác thực hoặc mã SDK Firebase khác theo kiểu mô-đun và vẫn biên dịch thành công ứng dụng của bạn bằng cả hai kiểu mã. Điều này cũng đúng đối với mã API mô-đun và không gian tên trong một sản phẩm như Cloud Firestore; kiểu mã mới và cũ có thể cùng tồn tại, miễn là bạn đang nhập các gói tương thích:

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

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

Hãy nhớ rằng, mặc dù ứng dụng của bạn sẽ biên dịch nhưng bạn sẽ không nhận được lợi ích về kích thước ứng dụng của mã mô-đun cho đến khi bạn loại bỏ hoàn toàn các câu lệnh và mã tương thích khỏi ứng dụng của mình.

Cập nhật mã khởi tạo

Cập nhật mã khởi tạo ứng dụng của bạn để sử dụng cú pháp mô-đun. Điều quan trọng là phải cập nhật mã này sau khi bạn hoàn thành việc tái cấu trúc tất cả mã trong ứng dụng của mình; điều này là do firebase.initializeApp() khởi tạo trạng thái chung cho cả API tương thích và API mô-đun, trong khi hàm mô-đun initializeApp() chỉ khởi tạo trạng thái cho mô-đun.

Trước: tương thích

import firebase from "firebase/compat/app"

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

Sau: mô-đun

import { initializeApp } from "firebase/app"

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

Xóa mã tương thích

Để nhận ra lợi ích về kích thước của API mô-đun, cuối cùng bạn nên chuyển đổi tất cả các lệnh gọi sang kiểu mô-đun được hiển thị ở trên và xóa tất cả các câu lệnh import "firebase/compat/* khỏi mã của bạn. Khi bạn thực hiện xong, sẽ không còn tài liệu tham khảo nào nữa vào không gian tên chung firebase.* hoặc bất kỳ mã nào khác theo kiểu API không gian tên.

Sử dụng thư viện tương thích từ cửa sổ

API mô-đun được tối ưu hóa để hoạt động với các mô-đun thay vì đối tượng window của trình duyệt. Các phiên bản trước của thư viện cho phép tải và quản lý Firebase bằng cách sử dụng không gian tên window.firebase . Điều này không được khuyến khích trong tương lai vì nó không cho phép loại bỏ mã không sử dụng. Tuy nhiên, phiên bản tương thích của SDK JavaScript hoạt động với window dành cho các nhà phát triển không muốn bắt đầu ngay lộ trình nâng cấp mô-đun.

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

Thư viện tương thích sử dụng mã mô-đun bên trong và cung cấp cho nó cùng một API như API được đặt tên; điều này có nghĩa là bạn có thể tham khảo đoạn mã được đặt tên và tham chiếu API được đặt tên để biết chi tiết. Phương pháp này không được khuyến khích sử dụng lâu dài mà chỉ để bắt đầu nâng cấp lên thư viện mô-đun đầy đủ.

Lợi ích và hạn chế của SDK mô-đun

SDK được mô-đun hóa hoàn toàn có những ưu điểm sau so với các phiên bản trước:

  • SDK mô-đun cho phép giảm đáng kể kích thước ứng dụng. Nó sử dụng định dạng Mô-đun JavaScript hiện đại, cho phép thực hiện "rung cây" trong đó bạn chỉ nhập các tạo phẩm mà ứng dụng của bạn cần. Tùy thuộc vào ứng dụng của bạn, việc rung cây bằng SDK mô-đun có thể giúp giảm 80% kilobyte so với ứng dụng tương đương được xây dựng bằng API không gian tên.
  • SDK mô-đun sẽ tiếp tục được hưởng lợi từ việc phát triển tính năng liên tục, trong khi API không gian tên thì không.