Verwenden von Modul-Bundlern mit Firebase

JavaScript-Modul-Bundler können viele Dinge tun, aber eine ihrer nützlichsten Funktionen ist die Möglichkeit, externe Bibliotheken in Ihrer Codebasis hinzuzufügen und zu verwenden. Modul-Bundler lesen Importpfade in Ihrem Code und kombinieren (bündeln) Ihren anwendungsspezifischen Code mit Ihrem importierten Bibliothekscode.

Ab Version 9 und höher ist die modulare Firebase-JavaScript-API für die Zusammenarbeit mit den Optimierungsfunktionen von Modul-Bundlern optimiert, um die Menge des in Ihrem endgültigen Build enthaltenen Firebase-Codes zu reduzieren.

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

Dieser Vorgang des Entfernens von ungenutztem Code aus einer Bibliothek wird als Tree Shaking bezeichnet. Es wäre äußerst zeitaufwändig und fehleranfällig, diesen Code manuell zu entfernen, aber Modul-Bundler können diese Entfernung automatisieren.

Es gibt viele hochwertige Modul-Bundler im JavaScript-Ökosystem. Dieser Leitfaden konzentriert sich auf die Verwendung von Firebase mit Webpack , Rollup und Esbuild .

Loslegen

Für diese Anleitung muss npm in Ihrer Entwicklungsumgebung installiert sein. npm wird zum Installieren und Verwalten von Abhängigkeiten (Bibliotheken) verwendet. Um npm zu installieren, installieren Sie Node.js , das npm automatisch einschließt.

Die meisten Entwickler sind ordnungsgemäß eingerichtet, sobald sie Node.js installiert haben. Es gibt jedoch häufige Probleme, auf die viele Entwickler beim Einrichten ihrer Umgebung stoßen. Wenn Fehler auftreten, stellen Sie sicher, dass Ihre Umgebung über die npm-CLI verfügt und dass Sie die richtigen Berechtigungen eingerichtet haben, damit Sie Pakete nicht als Administrator mit dem Befehl sudo installieren müssen .

package.json und die Installation von Firebase

Sobald Sie npm installiert haben, müssen Sie eine package.json Datei im Stammverzeichnis Ihres lokalen Projekts erstellen. Generieren Sie diese Datei mit dem folgenden npm-Befehl:

npm init

Dadurch werden Sie durch einen Assistenten geführt, der Ihnen die erforderlichen Informationen bereitstellt. Sobald die Datei erstellt ist, sieht sie etwa wie folgt aus:

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

  }
}

Diese Datei ist für viele verschiedene Dinge verantwortlich. Dies ist eine wichtige Datei, mit der Sie sich vertraut machen sollten, wenn Sie mehr über die Modulbündelung und die Erstellung von JavaScript-Code im Allgemeinen erfahren möchten. Der wichtige Teil dieses Leitfadens ist das Objekt "dependencies" . Dieses Objekt enthält ein Schlüssel-Wert-Paar der von Ihnen installierten Bibliothek und der von ihr verwendeten Version.

Das Hinzufügen von Abhängigkeiten erfolgt über den Befehl npm install oder npm i .

npm i firebase

Wenn Sie npm i firebase ausführen, aktualisiert der Installationsprozess package.json , um Firebase als Abhängigkeit aufzulisten:

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

Der Schlüssel ist der Name der Bibliothek und der Wert ist die zu verwendende Version. Der Versionswert ist flexibel und kann einen Wertebereich annehmen. Dies wird als semantische Versionierung oder Semver bezeichnet. Weitere Informationen zu Semver finden Sie im npm-Leitfaden zur semantischen Versionierung .

Quell- und Build-Ordner

Der von Ihnen geschriebene Code wird von einem Modul-Bundler gelesen und verarbeitet und dann als neue Datei oder Dateisatz ausgegeben. Es ist wichtig, diese beiden Dateitypen zu trennen. Der Code, den die Modul-Bundler lesen und verarbeiten, wird als „Quellcode“ bezeichnet. Die von ihnen ausgegebenen Dateien werden als Build- oder „Dist“-Code (Verteilungscode) bezeichnet.

Eine übliche Einrichtung in Codebasen besteht darin, den Quellcode in einem Ordner namens src und den erstellten Code in einem Ordner namens dist zu speichern.

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


- dist
 |_ bundle.js

Bedenken Sie in der obigen Beispieldateistruktur, dass index.js sowohl animations.js als auch datalist.js importiert. Wenn ein Modul-Bundler den Quellcode verarbeitet, erstellt er die Datei bundle.js im Ordner dist . Die bundle.js ist eine Kombination aus den Dateien im src Ordner und allen importierten Bibliotheken.

Wenn Sie Quellcodeverwaltungssysteme wie Git verwenden, ignorieren Sie häufig den Ordner dist , wenn Sie diesen Code im Haupt-Repository speichern.

Einstiegspunkte

Modul-Bundler haben alle das Konzept eines Einstiegspunkts. Sie können sich Ihre Anwendung als einen Dateibaum vorstellen. Eine Datei importiert Code aus einer anderen und so weiter und so fort. Das bedeutet, dass eine Datei die Wurzel des Baums sein wird. Diese Datei wird als Einstiegspunkt bezeichnet.

Schauen wir uns noch einmal das vorherige Beispiel einer Dateistruktur an.

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

Die Datei src/index.js gilt als Einstiegspunkt, da sie mit dem Import des gesamten benötigten Codes für die Anwendung beginnt. Diese Einstiegspunktdatei wird von Modulbündelern verwendet, um den Bündelungsprozess zu starten.

Verwenden von Firebase mit Webpack

Für Firebase-Apps und Webpack ist keine spezielle Konfiguration erforderlich. In diesem Abschnitt wird eine allgemeine Webpack-Konfiguration behandelt .

Der erste Schritt besteht darin, Webpack von npm als Entwicklungsabhängigkeit zu installieren.

npm i webpack webpack-cli -D

Erstellen Sie im Stammverzeichnis Ihres lokalen Projekts eine Datei mit dem Namen webpack.config.js und fügen Sie den folgenden Code hinzu.

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

Stellen Sie dann sicher, dass Firebase als Abhängigkeit installiert ist.

npm i firebase

Initialisieren Sie dann Firebase in Ihrer Codebasis. Der folgende Code importiert und initialisiert Firebase in einer Einstiegspunktdatei und verwendet Firestore Lite, um ein „Stadt“-Dokument zu laden.

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

Der nächste Schritt besteht darin, ein npm-Skript hinzuzufügen , um den Webpack-Build auszuführen. Öffnen Sie die Datei package.json und fügen Sie das folgende Schlüssel-Wert-Paar zum Objekt "scripts" hinzu.

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

Um Webpack auszuführen und den Build-Ordner zu generieren, führen Sie den folgenden Befehl aus.

npm run build

Überprüfen Sie abschließend den dist Build-Ordner. Es sollte eine Datei mit dem Namen bundle.js enthalten, die Ihre gebündelte Anwendung und Ihren Abhängigkeitscode enthält.

Weitere Informationen zur Optimierung Ihres Webpack-Builds für die Produktion finden Sie in der offiziellen Dokumentation zur Konfigurationseinstellung „mode“ .

Verwenden von Firebase mit Rollup

Für Firebase-Apps und Rollup ist keine spezielle Konfiguration erforderlich. In diesem Abschnitt wird eine allgemeine Rollup-Konfiguration behandelt.

Der erste Schritt besteht darin, Rollup und ein Plugin zu installieren, das zum Zuordnen von Importen zu Abhängigkeiten verwendet wird, die mit npm installiert wurden.

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

Erstellen Sie im Stammverzeichnis Ihres lokalen Projekts eine Datei mit dem Namen rollup.config.js und fügen Sie den folgenden Code hinzu.

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

Initialisieren Sie dann Firebase in Ihrer Codebasis. Der folgende Code importiert und initialisiert Firebase in einer Einstiegspunktdatei und verwendet Firestore Lite, um ein „Stadt“-Dokument zu laden.

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

Der nächste Schritt besteht darin, ein npm-Skript hinzuzufügen , um den Rollup-Build auszuführen. Öffnen Sie die Datei package.json und fügen Sie das folgende Schlüssel-Wert-Paar zum Objekt "scripts" hinzu.

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

Führen Sie den folgenden Befehl aus, um das Rollup auszuführen und den Build-Ordner zu generieren.

npm run build

Überprüfen Sie abschließend den dist Build-Ordner. Es sollte eine Datei mit dem Namen bundle.js enthalten, die Ihre gebündelte Anwendung und Ihren Abhängigkeitscode enthält.

Weitere Informationen zur Optimierung Ihres Rollup-Builds für die Produktion finden Sie in der offiziellen Dokumentation zu Plugins für Produktions-Builds .

Verwenden von Firebase mit esbuild

Für Firebase-Apps und Esbuild ist keine spezielle Konfiguration erforderlich. In diesem Abschnitt wird eine allgemeine Esbuild-Konfiguration behandelt.

Der erste Schritt besteht darin, esbuild als Entwicklungsabhängigkeit zu installieren.

npm i esbuild -D

Erstellen Sie im Stammverzeichnis Ihres lokalen Projekts eine Datei mit dem Namen esbuild.config.js und fügen Sie den folgenden Code hinzu.

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

Initialisieren Sie dann Firebase in Ihrer Codebasis. Der folgende Code importiert und initialisiert Firebase in einer Einstiegspunktdatei und verwendet Firestore Lite, um ein „Stadt“-Dokument zu laden.

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

Der nächste Schritt besteht darin, ein NPM-Skript hinzuzufügen , um esbuild auszuführen. Öffnen Sie die Datei package.json und fügen Sie das folgende Schlüssel-Wert-Paar zum Objekt "scripts" hinzu.

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

Überprüfen Sie abschließend den dist Build-Ordner. Es sollte eine Datei mit dem Namen bundle.js enthalten, die Ihre gebündelte Anwendung und Ihren Abhängigkeitscode enthält.

Weitere Informationen zur Optimierung von esbuild für die Produktion finden Sie in der offiziellen Dokumentation zu Minimierung und anderen Optimierungen .