Sử dụng trình gói mô-đun với Firebase

Trình gói mô-đun JavaScript có thể làm nhiều việc, nhưng một trong những tính năng hữu ích nhất là khả năng thêm và sử dụng các thư viện bên ngoài trong cơ sở mã của bạn. Các trình gói mô-đun sẽ đọc các đường dẫn nhập trong mã của bạn và kết hợp (gói) mã dành riêng cho ứng dụng với mã thư viện đã nhập.

Từ phiên bản 9 trở lên, API mô-đun JavaScript của Firebase được tối ưu hoá để hoạt động với các tính năng tối ưu hoá của bộ gói mô-đun nhằm giảm số lượng mã Firebase có trong bản dựng hoàn chỉnh.

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, getRedirectResult } from 'firebase/auth';

const firebaseApp = initializeApp({ /* config */ });
const auth = getAuth(firebaseApp);
onAuthStateChanged(auth, user => { /* check status */ });

/**
 * getRedirectResult is unused and should not be included in the code base.
 * In addition, there are many other functions within firebase/auth that are
 * not imported and therefore should not be included as well.
 */

Quá trình loại bỏ mã không sử dụng khỏi thư viện này được gọi là rung cây. Việc xoá mã này theo cách thủ công sẽ rất tốn thời gian và dễ xảy ra lỗi, nhưng các trình gói mô-đun có thể tự động hoá việc xoá này.

Có nhiều trình gói mô-đun chất lượng cao trong hệ sinh thái JavaScript. Hướng dẫn này tập trung trình bày cách sử dụng Firebase bằng webpack, Cuộn lênbản dựng.

Bắt đầu

Hướng dẫn này yêu cầu bạn phải cài đặt npm trong môi trường phát triển của mình. npm được dùng để cài đặt và quản lý các phần phụ thuộc (thư viện). Để cài đặt npm, hãy cài đặt Node.js (tự động bao gồm npm).

Hầu hết các nhà phát triển đều được thiết lập đúng cách sau khi cài đặt Node.js. Tuy nhiên, nhiều nhà phát triển gặp phải những vấn đề phổ biến khi thiết lập môi trường. Nếu bạn gặp lỗi, hãy đảm bảo môi trường của bạn có npm CLI và bạn đã thiết lập các quyền phù hợp để không phải cài đặt các gói với tư cách là quản trị viên bằng lệnh sudo.

package.json và cài đặt Firebase

Sau khi cài đặt npm, bạn cần tạo tệp package.json ở thư mục gốc của dự án cục bộ. Tạo tệp này bằng lệnh npm sau:

npm init

Thao tác này sẽ đưa bạn đến trình hướng dẫn để cung cấp thông tin cần thiết. Sau khi được tạo, tệp sẽ có dạng như sau:

{
  "name": "your-package-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {

  }
}

Tệp này chịu trách nhiệm về nhiều vấn đề. Đây là một tệp quan trọng mà bạn nên làm quen nếu muốn tìm hiểu thêm về việc đóng gói mô-đun và tạo mã JavaScript nói chung. Phần quan trọng của hướng dẫn này là đối tượng "dependencies". Đối tượng này sẽ lưu một cặp khoá-giá trị của thư viện mà bạn đã cài đặt và phiên bản mà thư viện đang sử dụng.

Bạn có thể thêm phần phụ thuộc thông qua lệnh npm install hoặc npm i.

npm i firebase

Khi bạn chạy npm i firebase, quá trình cài đặt sẽ cập nhật package.json để liệt kê Firebase làm phần phụ thuộc:

  "dependencies": {
    "firebase": "^9.0.0"
  },

Khoá là tên của thư viện và giá trị là phiên bản cần sử dụng. Giá trị phiên bản linh hoạt và có thể chấp nhận nhiều giá trị. Đây được gọi là tạo phiên bản ngữ nghĩa hoặc semver. Để tìm hiểu thêm về semver, hãy xem hướng dẫn của npm về cách tạo phiên bản ngữ nghĩa.

Thư mục nguồn và thư mục bản dựng

Mã bạn viết sẽ được trình đóng gói mô-đun đọc và xử lý và sau đó được xuất dưới dạng tệp hoặc tập hợp tệp mới. Bạn cần phải tách riêng hai loại tệp này. Mã mà bộ gói mô-đun đọc và xử lý được gọi là mã "nguồn". Các tệp mà chúng xuất ra được gọi là mã xây dựng (build) hoặc mã "dist" (phân phối).

Một cách thiết lập phổ biến trong cơ sở mã là lưu trữ mã nguồn trong một thư mục có tên là src và mã đã tạo trong thư mục có tên là dist.

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js

Trong cấu trúc tệp ví dụ ở trên, hãy lưu ý rằng index.js nhập cả animations.jsdatalist.js. Khi bộ gói mô-đun xử lý mã nguồn, trình tạo gói sẽ tạo ra tệp bundle.js trong thư mục dist. bundle.js là tổ hợp các tệp trong thư mục src và mọi thư viện mà bạn nhập.

Nếu đang sử dụng các hệ thống kiểm soát nguồn như Git, thì bạn nên bỏ qua thư mục dist khi lưu trữ mã này trong kho lưu trữ chính.

Điểm truy cập

Tất cả các trình gói mô-đun đều có khái niệm về điểm truy cập. Bạn có thể xem ứng dụng là một cây tệp. Một tệp nhập mã từ một tệp khác, v.v. và cứ thế tiếp tục. Điều này có nghĩa là một tệp sẽ là gốc của cây. Tệp này được gọi là điểm truy cập.

Hãy xem lại ví dụ về cấu trúc tệp trước.

- src
 |_ index.js
 |_ animations.js
 |_ datalist.js


- dist
 |_ bundle.js
// src/index.js
import { animate } from './animations';
import { createList } from './datalist';

// This is not real code, but for example purposes only
const theList = createList('users/123/tasks');
theList.addEventListener('loaded', event => {
  animate(theList);
});

Tệp src/index.js được coi là điểm truy cập vì tệp này bắt đầu nhập tất cả mã cần thiết cho ứng dụng. Tệp điểm truy cập này được các trình gói mô-đun sử dụng để bắt đầu quá trình gói.

Sử dụng Firebase với webpack

Không cần cấu hình cụ thể cho gói web và ứng dụng Firebase. Phần này đề cập đến cấu hình gói web chung.

Bước đầu tiên là cài đặt webpack từ npm dưới dạng phần phụ thuộc phát triển.

npm i webpack webpack-cli -D

Tạo một tệp ở gốc của dự án cục bộ có tên là webpack.config.js và thêm mã sau.

const path = require('path');

module.exports = {
  // The entry point file described above
  entry: './src/index.js',
  // The location of the build folder described above
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  devtool: 'eval-source-map',
};

Sau đó, hãy đảm bảo bạn đã cài đặt Firebase làm phần phụ thuộc.

npm i firebase

Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Đoạn mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập và sử dụng Firestore Lite để tải tài liệu "thành phố".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

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

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

Bước tiếp theo là thêm tập lệnh npm để chạy bản dựng webpack. Mở tệp package.json và thêm cặp khoá-giá trị sau đây vào đối tượng "scripts".

  "scripts": {
    "build": "webpack --mode=development"
  },

Để chạy gói web và tạo thư mục bản dựng, hãy chạy lệnh sau.

npm run build

Cuối cùng, hãy kiểm tra thư mục bản dựng dist. Tệp này phải chứa một tệp có tên bundle.js, trong đó chứa mã ứng dụng và mã phần phụ thuộc đi kèm.

Để biết thêm thông tin về cách tối ưu hoá bản dựng webpack để phát hành công khai, hãy xem tài liệu chính thức về chế độ cài đặt cấu hình.

Sử dụng Firebase với công cụ hợp nhất

Bạn không cần phải thiết lập cấu hình cụ thể cho các ứng dụng và công cụ hợp nhất Firebase. Phần này đề cập đến cấu hình hợp nhất chung.

Bước đầu tiên là cài đặt Cuộn và một trình bổ trợ dùng để ánh xạ dữ liệu nhập đến các phần phụ thuộc được cài đặt bằng npm.

npm i rollup @rollup/plugin-node-resolve -D

Tạo một tệp ở gốc của dự án cục bộ có tên là rollup.config.js và thêm mã sau.

import { nodeResolve } from '@rollup/plugin-node-resolve';

export default {
  // the entry point file described above
  input: 'src/index.js',
  // the output for the build folder described above
  output: {
    file: 'dist/bundle.js',
    // Optional and for development only. This provides the ability to
    // map the built code back to the original source format when debugging.
    sourcemap: 'inline',
    // Configure Rollup to convert your module code to a scoped function
    // that "immediate invokes". See the Rollup documentation for more
    // information: https://rollupjs.org/guide/en/#outputformat
    format: 'iife'
  },
  // Add the plugin to map import paths to dependencies
  // installed with npm
  plugins: [nodeResolve()]
};

Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Đoạn mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập và sử dụng Firestore Lite để tải tài liệu "thành phố".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

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

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

Bước tiếp theo là thêm tập lệnh npm để chạy bản dựng hợp nhất. Mở tệp package.json và thêm cặp khoá-giá trị sau đây vào đối tượng "scripts".

  "scripts": {
    "build": "rollup -c rollup.config.js"
  },

Để chạy tính năng hợp nhất và tạo thư mục bản dựng, hãy chạy lệnh sau.

npm run build

Cuối cùng, hãy kiểm tra thư mục bản dựng dist. Tệp này phải chứa một tệp có tên bundle.js, trong đó chứa mã ứng dụng và mã phần phụ thuộc đi kèm.

Để biết thêm thông tin về cách tối ưu hoá bản dựng hợp nhất để phát hành công khai, hãy xem tài liệu chính thức về trình bổ trợ cho bản dựng phát hành công khai.

Sử dụng Firebase với esbuild

Không cần cấu hình cụ thể cho bản dựng và các ứng dụng Firebase. Phần này đề cập đến cấu hình bản dựng chung.

Bước đầu tiên là cài đặt bản dựng esbuild dưới dạng phần phụ thuộc phát triển.

npm i esbuild -D

Tạo một tệp ở gốc của dự án cục bộ có tên là esbuild.config.js và thêm mã sau.

require('esbuild').build({
  // the entry point file described above
  entryPoints: ['src/index.js'],
  // the build folder location described above
  outfile: 'dist/bundle.js',
  bundle: true,
  // Replace with the browser versions you need to target
  target: ['chrome60', 'firefox60', 'safari11', 'edge20'],
  // Optional and for development only. This provides the ability to
  // map the built code back to the original source format when debugging.
  sourcemap: 'inline',
}).catch(() => process.exit(1))

Sau đó, hãy khởi chạy Firebase trong cơ sở mã của bạn. Đoạn mã sau đây nhập và khởi chạy Firebase trong tệp điểm truy cập và sử dụng Firestore Lite để tải tài liệu "thành phố".

// src/index.js
import { initializeApp } from 'firebase/app';
import { getFirestore, doc, getDoc } from 'firebase/firestore/lite';

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

async function loadCity(name) {
  const cityDoc = doc(db, `cities/${name}`);
  const snapshot = await getDoc(cityDoc);
  return {
    id: snapshot.id,
    ...snapshot.data(),
  };
}

Bước tiếp theo là thêm tập lệnh npm để chạy bản dựng. Mở tệp package.json và thêm cặp khoá-giá trị sau đây vào đối tượng "scripts".

  "scripts": {
    "build": "node ./esbuild.config.js"
  },

Cuối cùng, hãy kiểm tra thư mục bản dựng dist. Tệp này phải chứa một tệp có tên bundle.js, trong đó chứa mã ứng dụng và mã phần phụ thuộc đi kèm.

Để biết thêm thông tin về cách tối ưu hoá bản dựng cho phiên bản phát hành công khai, hãy xem tài liệu chính thức về cách giảm thiểu và các biện pháp tối ưu hoá khác.