Korzystanie z pakietów pakietów modułów z Firebase

Moduły JavaScript mogą robić wiele rzeczy, ale jedną z najbardziej przydatnych funkcji jest możliwość dodawania i używania w kodzie bibliotek zewnętrznych. Programy do łączenia modułów odczytują ścieżki importu w kodzie i łączą (pakują) kod aplikacji z zaimportowanym kodem biblioteki.

Od wersji 9 i nowszych modułowy interfejs API JavaScript Firebase jest zoptymalizowany pod kątem współpracy z funkcjami optymalizacji narzędzi do tworzenia pakietów modułów, aby zmniejszyć ilość kodu Firebase uwzględnianego w ostatecznej kompilacji.

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

Proces eliminowania nieużywanego kodu z biblioteki jest nazywany tree shaking. Ręczne usuwanie tego kodu byłoby bardzo czasochłonne i obarczone ryzykiem błędów, ale narzędzia do pakowania modułów mogą zautomatyzować ten proces.

W ekosystemie JavaScript jest wiele wysokiej jakości narzędzi do łączenia modułów. Ten przewodnik dotyczy korzystania z Firebase w połączeniu z webpackiem, Rollupemesbuildem.

Rozpocznij

W tym przewodniku założono, że w środowisku programistycznym masz zainstalowany menedżer pakietów npm. Służy on do instalowania zależności (bibliotek) i zarządzania nimi. Aby zainstalować npm, zainstaluj Node.js, który automatycznie zawiera npm.

Większość deweloperów może zacząć pracę po zainstalowaniu Node.js. Jednak podczas konfigurowania środowiska wielu deweloperów napotyka typowe problemy. Jeśli napotkasz błędy, upewnij się, że w środowisku jest zainstalowany wiersz poleceń npm i że masz odpowiednie uprawnienia, aby nie trzeba było instalować pakietów jako administrator za pomocą polecenia sudo.

package.json i instalowanie Firebase

Po zainstalowaniu npm musisz utworzyć plik package.json w katalogu głównym projektu lokalnego. Wygeneruj ten plik za pomocą tego polecenia npm:

npm init

Kreator przeprowadzi Cię przez proces podawania wymaganych informacji. Po utworzeniu plik będzie wyglądać mniej więcej tak:

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

  }
}

Ten plik odpowiada za wiele różnych rzeczy. Jeśli chcesz dowiedzieć się więcej o pakowaniu modułów i tworzeniu kodu JavaScript, warto zapoznać się z tym plikiem. Ważnym elementem tego przewodnika jest obiekt "dependencies". Ten obiekt będzie zawierać parę klucz-wartość zainstalowanej biblioteki i używanej przez nią wersji.

Zależności dodaje się za pomocą polecenia npm install lub npm i.

npm i firebase

Gdy uruchomisz polecenie npm i firebase, proces instalacji zaktualizuje package.json, aby wyświetlić Firebase jako zależność:

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

Kluczem jest nazwa biblioteki, a wartością – wersja do użycia. Wartość wersji jest elastyczna i może przyjmować różne wartości. Jest to tzw. wersjonowanie semantyczne lub semver. Więcej informacji o semver znajdziesz w przewodniku npm dotyczącym wersji semantycznych.

Foldery źródłowe a foldery kompilacji

Napisany przez Ciebie kod jest odczytywany i przetwarzany przez narzędzie do łączenia modułów, a następnie zapisywany jako nowy plik lub zestaw plików. Ważne jest, aby rozdzielić te 2 typy plików. Kod, który czytają i przetwarzają narzędzia do łączenia modułów, jest nazywany kodem „źródłowym”. Pliki wyjściowe są nazywane skompilowanym kodem lub kodem „dist” (dystrybucyjnym).

W bazach kodu często stosuje się konfigurację, w której kod źródłowy jest przechowywany w folderze o nazwie src, a skompilowany kod w folderze o nazwie dist.

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


- dist
 |_ bundle.js

W przykładzie struktury plików powyżej załóżmy, że index.js importuje zarówno animations.js, jak i datalist.js. Gdy narzędzie do łączenia modułów przetworzy kod źródłowy, utworzy plik bundle.js w folderze dist. bundle.js to połączenie plików z folderu src i wszystkich bibliotek, które importuje.

Jeśli używasz systemów kontroli źródła, takich jak Git, często ignoruje się folder dist podczas przechowywania tego kodu w głównym repozytorium.

Punkty wejścia

Wszystkie narzędzia do łączenia modułów mają pojęcie punktu wejścia. Aplikację możesz traktować jako drzewo plików. Jeden plik importuje kod z innego i tak dalej. Oznacza to, że jeden plik będzie korzeniem drzewa. Ten plik jest znany jako punkt wejścia.

Wróćmy do poprzedniego przykładu struktury plików.

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

Plik src/index.js jest uważany za punkt wejścia, ponieważ rozpoczyna importowanie całego kodu potrzebnego do działania aplikacji. Ten plik punktu wejścia jest używany przez narzędzia do łączenia modułów do rozpoczęcia procesu łączenia.

Korzystanie z Firebase w webpacku

W przypadku aplikacji Firebase i webpacka nie jest wymagana żadna specjalna konfiguracja. Ta sekcja zawiera ogólną konfigurację webpacka.

Pierwszym krokiem jest zainstalowanie webpacka z npm jako zależności deweloperskiej.

npm i webpack webpack-cli -D

Utwórz w katalogu głównym projektu lokalnego plik o nazwie webpack.config.js i dodaj ten kod.

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

Następnie sprawdź, czy Firebase jest zainstalowany jako zależność.

npm i firebase

Następnie zainicjuj Firebase w bazie kodu. Ten kod importuje i inicjuje Firebase w pliku punktu wejścia oraz używa Firestore Lite do wczytania dokumentu „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(),
  };
}

Następnym krokiem jest dodanie skryptu npm, który uruchomi kompilację webpack. Otwórz plik package.json i dodaj do obiektu "scripts" tę parę klucz-wartość:

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

Aby uruchomić webpack i wygenerować folder kompilacji, uruchom to polecenie.

npm run build

Na koniec sprawdź folder kompilacji dist. Powinien on zawierać plik o nazwie bundle.js, który zawiera spakowaną aplikację i kod zależności.

Więcej informacji o optymalizowaniu kompilacji webpack na potrzeby środowiska produkcyjnego znajdziesz w oficjalnej dokumentacji dotyczącej ustawienia konfiguracji „mode”.

Korzystanie z Firebase z Rollup

W przypadku aplikacji Firebase i Rollup nie jest wymagana żadna specjalna konfiguracja. Ta sekcja zawiera ogólną konfigurację scalania.

Pierwszym krokiem jest zainstalowanie Rollup i wtyczki używanej do mapowania importów na zależności zainstalowane za pomocą npm.

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

Utwórz w katalogu głównym projektu lokalnego plik o nazwie rollup.config.js i dodaj do niego ten kod:

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

Następnie zainicjuj Firebase w bazie kodu. Ten kod importuje i inicjuje Firebase w pliku punktu wejścia oraz używa Firestore Lite do wczytania dokumentu „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(),
  };
}

Następnym krokiem jest dodanie skryptu npm, który uruchomi kompilację Rollup. Otwórz plik package.json i dodaj do obiektu "scripts" tę parę klucz-wartość:

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

Aby uruchomić rollup i wygenerować folder kompilacji, uruchom to polecenie.

npm run build

Na koniec sprawdź folder kompilacji dist. Powinien on zawierać plik o nazwie bundle.js, który zawiera spakowaną aplikację i kod zależności.

Więcej informacji o optymalizacji kompilacji Rollup pod kątem produkcji znajdziesz w oficjalnej dokumentacji wtyczek do kompilacji produkcyjnych.

Korzystanie z Firebase z esbuild

W przypadku aplikacji Firebase i esbuild nie jest wymagana żadna specjalna konfiguracja. W tej sekcji znajdziesz ogólną konfigurację esbuild.

Pierwszym krokiem jest zainstalowanie esbuild jako zależności deweloperskiej.

npm i esbuild -D

Utwórz w katalogu głównym projektu lokalnego plik o nazwie esbuild.config.js i dodaj ten kod.

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

Następnie zainicjuj Firebase w bazie kodu. Ten kod importuje i inicjuje Firebase w pliku punktu wejścia oraz używa Firestore Lite do wczytania dokumentu „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(),
  };
}

Następnym krokiem jest dodanie skryptu npm, który uruchomi esbuild. Otwórz plik package.json i dodaj do obiektu "scripts" tę parę klucz-wartość:

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

Na koniec sprawdź folder kompilacji dist. Powinien on zawierać plik o nazwie bundle.js, który zawiera spakowaną aplikację i kod zależności.

Więcej informacji o optymalizacji esbuild pod kątem produkcji znajdziesz w oficjalnej dokumentacji na temat minifikacji i innych optymalizacji.