Menggunakan pemaket modul dengan Firebase

Pemaket modul JavaScript dapat melakukan banyak hal, tetapi salah satu fitur yang paling berguna adalah kemampuannya untuk menambahkan dan menggunakan library eksternal dalam code base. Pemaket modul membaca jalur impor dalam kode dan menggabungkan (memaketkan) kode khusus aplikasi dengan kode library yang diimpor.

Di versi 9 dan yang lebih tinggi, API modular Firebase JavaScript dioptimalkan agar bisa berfungsi dengan fitur pengoptimalan pemaket modul untuk mengurangi jumlah kode Firebase yang disertakan dalam build akhir.

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.
 */

Proses menghapus kode yang tidak digunakan dari library dikenal sebagai tree shaking. Penghapusan kode ini secara manual akan sangat menyita waktu dan rentan error, tetapi pemaket modul dapat mengotomatiskan prosesnya.

Ada banyak pemaket modul berkualitas tinggi dalam ekosistem JavaScript. Panduan ini fokus membahas penggunaan Firebase dengan webpack, Rollup, dan esbuild.

Memulai

Panduan ini mengharuskan Anda menginstal npm di lingkungan pengembangan. npm digunakan untuk menginstal dan mengelola dependensi (library). Untuk menginstal npm, instal Node.js, yang menyertakan npm secara otomatis.

Setelah menginstal Node.js, kebanyakan developer siap memulai. Namun, ada masalah umum yang dihadapi banyak developer saat menyiapkan lingkungannya. Jika terjadi error, pastikan lingkungan Anda memiliki CLI npm dan Anda telah menyiapkan izin yang benar agar tidak perlu menginstal paket sebagai administrator dengan perintah sudo.

package.json dan menginstal Firebase

Setelah menginstal npm, Anda perlu membuat file package.json di root project lokal. Buat file ini dengan perintah npm berikut:

npm init

Tindakan ini akan meminta Anda mengikuti wizard untuk memberikan informasi yang diperlukan. Setelah dibuat, file akan terlihat seperti berikut:

{
  "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": {

  }
}

File ini diperlukan untuk berbagai hal. Pahami file ini dengan baik jika Anda ingin mempelajari lebih lanjut cara memaketkan modul dan cara mem-build kode JavaScript secara umum. Objek "dependencies" merupakan bagian penting dalam panduan ini. Objek ini akan menyimpan key-value pair library yang Anda instal dan versi yang digunakannya.

Penambahan dependensi dilakukan melalui perintah npm install atau npm i.

npm i firebase

Saat Anda menjalankan npm i firebase, proses penginstalan akan memperbarui package.json untuk mencantumkan Firebase sebagai dependensi:

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

Kuncinya adalah nama library dan nilainya adalah versi yang akan digunakan. Nilai versi ini fleksibel dan dapat menerima rentang nilai. Hal ini dikenal sebagai semantic versioning atau semver. Untuk mempelajari semver lebih lanjut, lihat panduan npm tentang semantic versioning.

Folder sumber vs folder build

Kode yang Anda tulis dibaca dan diproses oleh pemaket modul, lalu dikeluarkan sebagai satu atau sekumpulan file baru. Anda harus memisahkan kedua jenis file ini. Kode yang dibaca dan diproses pemaket modul dikenal sebagai kode "sumber". File yang dihasilkan dikenal sebagai kode build atau kode "dist" (distribusi).

Penyiapan dalam code base biasanya berupa penyimpanan kode sumber ke folder bernama src dan kode build ke folder bernama dist.

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


- dist
 |_ bundle.js

Dalam contoh struktur file di atas, perhatikan bahwa index.js mengimpor animations.js dan datalist.js. Saat memproses kode sumber, pemaket modul akan menghasilkan file bundle.js di folder dist. bundle.js adalah kombinasi berbagai file dalam folder src dan juga library yang diimpor.

Jika menggunakan sistem kontrol sumber seperti Git, sebaiknya abaikan folder dist saat menyimpan kode ini di repositori utama.

Titik entri

Semua pemaket modul memiliki konsep titik entri. Anggap aplikasi Anda sebagai pohon file. Satu file mengimpor kode dari file lainnya dan seterusnya. Ini berarti bahwa satu file tersebut akan menjadi akar pohon tersebut. File ini dikenal sebagai titik entri.

Mari lihat kembali contoh struktur file sebelumnya.

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

File src/index.js dianggap sebagai titik entri karena memulai impor semua kode yang diperlukan untuk aplikasi. File titik entri ini digunakan pemaket modul untuk memulai proses pemaketan.

Menggunakan Firebase dengan webpack

Tidak ada konfigurasi khusus yang diperlukan untuk aplikasi Firebase dan webpack. Bagian ini membahas konfigurasi webpack umum.

Langkah pertama adalah menginstal webpack dari npm sebagai dependensi pengembangan.

npm i webpack webpack-cli -D

Buat file di root project lokal Anda yang bernama webpack.config.js dan tambahkan kode berikut.

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',
};

Kemudian, pastikan Firebase telah diinstal sebagai dependensi.

npm i firebase

Selanjutnya, inisialisasi Firebase dalam code base Anda. Kode berikut mengimpor dan menginisialisasi Firebase dalam file titik entri dan menggunakan Firestore Lite untuk memuat dokumen "city".

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

Langkah selanjutnya adalah menambahkan skrip npm untuk menjalankan build webpack. Buka file package.json dan tambahkan key-value pair berikut ke objek "scripts".

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

Untuk menjalankan webpack dan membuat folder build, jalankan perintah berikut.

npm run build

Terakhir, periksa folder build dist. Folder seharusnya berisi file bernama bundle.js yang berisi paket aplikasi dan kode dependensi Anda.

Untuk informasi selengkapnya mengenai cara mengoptimalkan build webpack untuk produksi, lihat dokumentasi resmi tentang setelan konfigurasi "mode".

Menggunakan Firebase dengan Rollup

Tidak ada konfigurasi khusus yang diperlukan untuk aplikasi Firebase dan Rollup. Bagian ini membahas konfigurasi Rollup umum.

Langkah pertama adalah menginstal Rollup dan plugin yang digunakan untuk memetakan impor ke dependensi yang diinstal dengan npm.

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

Buat file di root project lokal Anda yang bernama rollup.config.js dan tambahkan kode berikut.

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

Selanjutnya, inisialisasi Firebase dalam code base Anda. Kode berikut mengimpor dan menginisialisasi Firebase dalam file titik entri dan menggunakan Firestore Lite untuk memuat dokumen "city".

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

Langkah selanjutnya adalah menambahkan skrip npm untuk menjalankan build rollup. Buka file package.json dan tambahkan key-value pair berikut ke objek "scripts".

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

Untuk menjalankan rollup dan membuat folder build, jalankan perintah berikut.

npm run build

Terakhir, periksa folder build dist. Folder seharusnya berisi file bernama bundle.js yang berisi paket aplikasi dan kode dependensi Anda.

Untuk informasi selengkapnya terkait cara mengoptimalkan build Rollup untuk produksi, lihat dokumentasi resmi tentang plugin untuk build produksi.

Menggunakan Firebase dengan esbuild

Tidak ada konfigurasi khusus yang diperlukan untuk aplikasi Firebase dan esbuild. Bagian ini membahas konfigurasi esbuild umum.

Langkah pertama adalah menginstal esbuild sebagai dependensi pengembangan.

npm i esbuild -D

Buat file di root project lokal Anda yang bernama esbuild.config.js dan tambahkan kode berikut.

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

Selanjutnya, inisialisasi Firebase dalam code base Anda. Kode berikut mengimpor dan menginisialisasi Firebase dalam file titik entri dan menggunakan Firestore Lite untuk memuat dokumen "city".

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

Langkah selanjutnya adalah menambahkan skrip npm untuk menjalankan esbuild. Buka file package.json dan tambahkan key-value pair berikut ke objek "scripts".

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

Terakhir, periksa folder build dist. Folder seharusnya berisi file bernama bundle.js yang berisi paket aplikasi dan kode dependensi Anda.

Untuk informasi selengkapnya terkait cara mengoptimalkan esbuild untuk produksi, baca dokumentasi resmi tentang minifikasi dan pengoptimalan lainnya.