Usługi tworzenia pakietów modułów JavaScript mogą robić wiele rzeczy, ale jedną z ich najbardziej przydatnych funkcji jest możliwość dodawania i używania bibliotek zewnętrznych w bazie kodu. Usługi tworzenia pakietów modułów odczytują ścieżki importu w kodzie i łączą (pakują) kod specyficzny dla aplikacji z kodem zaimportowanej biblioteki.
Od wersji 9 i nowszych modułowy interfejs API Firebase JavaScript jest zoptymalizowany pod kątem współpracy z funkcjami optymalizacji usług tworzenia pakietów modułów, aby zmniejszyć ilość kodu Firebase zawartego 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.
*/
Ten proces eliminowania nieużywanego kodu z biblioteki jest nazywany tree shaking. Ręczne usuwanie tego kodu byłoby niezwykle czasochłonne i podatne na błędy, ale usługi tworzenia pakietów modułów mogą zautomatyzować to usuwanie.
W ekosystemie JavaScript jest wiele wysokiej jakości usług tworzenia pakietów modułów. Ten przewodnik koncentruje się na używaniu Firebase z webpack, Rollup i esbuild.
Rozpocznij
Ten przewodnik wymaga zainstalowania npm w środowisku programistycznym. npm służy do instalowania i zarządzania zależnościami (bibliotekami). Aby zainstalować npm, zainstaluj Node.js, który automatycznie zawiera npm.
Większość deweloperów jest prawidłowo skonfigurowana po zainstalowaniu Node.js. Podczas konfigurowania środowiska wielu deweloperów napotyka jednak typowe problemy. Jeśli wystąpią jakiekolwiek błędy, upewnij się, że w środowisku jest zainstalowany interfejs CLI 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 swojego projektu lokalnego. Wygeneruj ten plik za pomocą tego polecenia npm:
npm init
Spowoduje to uruchomienie kreatora, który poprosi Cię o podanie wymaganych informacji. Po utworzeniu plik będzie wyglądać podobnie do tego:
{
"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 tworzeniu pakietów modułów i ogólnie o 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 plik package.json, aby Firebase był wymieniony jako zależność:
"dependencies": {
"firebase": "^9.0.0"
},
Kluczem jest nazwa biblioteki, a wartością – wersja, której należy użyć. Wartość wersji jest elastyczna i może przyjmować zakres wartości. Jest to tzw. wersjonowanie semantyczne lub semver. Więcej informacji o semver, znajdziesz w przewodniku npm na temat wersjonowania semantycznego.
Foldery źródłowe i kompilacji
Napisany przez Ciebie kod jest odczytywany i przetwarzany przez usługę tworzenia pakietów 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 usługi tworzenia pakietów modułów odczytują i przetwarzają, jest nazywany kodem „źródłowym”. Pliki, które tworzą, są nazywane kodem skompilowanym lub „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 kod skompilowany – w folderze o nazwie dist.
- src
|_ index.js
|_ animations.js
|_ datalist.js
- dist
|_ bundle.js
W powyższej przykładowej strukturze plików załóżmy, że plik index.js importuje zarówno plik animations.js, jak i datalist.js. Gdy usługa tworzenia pakietów modułów przetworzy kod źródłowy, utworzy plik bundle.js w folderze dist. Plik bundle.js to połączenie plików z folderu src i wszystkich importowanych bibliotek.
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 usługi tworzenia pakietów modułów mają pojęcie punktu wejścia. Aplikację można 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 nazywany punktem 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 potrzebnego kodu aplikacji. Ten plik punktu wejścia jest używany przez usługi tworzenia pakietów modułów do rozpoczęcia procesu tworzenia pakietu.
Używanie Firebase z webpack
W przypadku aplikacji Firebase i webpack nie jest wymagana żadna specjalna konfiguracja. Ta sekcja zawiera ogólną konfigurację webpack.
Pierwszym krokiem jest zainstalowanie webpack z npm jako zależności deweloperskiej.
npm i webpack webpack-cli -D
Utwórz plik w katalogu głównym swojego projektu lokalnego 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 upewnij się, że 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
do uruchamiania kompilacji webpack. Otwórz plik package.json
i dodaj tę parę klucz-wartość do obiektu "scripts".
"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 pod kątem środowiska produkcyjnego znajdziesz w ich oficjalnej dokumentacji dotyczącej ustawienia konfiguracji „mode”.
Używanie Firebase z Rollup
W przypadku aplikacji Firebase i Rollup nie jest wymagana żadna specjalna konfiguracja. Ta sekcja zawiera ogólną konfigurację Rollup.
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 plik w katalogu głównym swojego projektu lokalnego o nazwie rollup.config.js i dodaj 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
do uruchamiania kompilacji Rollup. Otwórz plik package.json
i dodaj tę parę klucz-wartość do obiektu "scripts".
"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 optymalizowaniu kompilacji Rollup pod kątem środowiska produkcyjnego znajdziesz w ich oficjalnej dokumentacji dotyczącej wtyczek do kompilacji produkcyjnych.
Używanie Firebase z esbuild
W przypadku aplikacji Firebase i esbuild nie jest wymagana żadna specjalna konfiguracja. Ta sekcja zawiera ogólną konfigurację esbuild.
Pierwszym krokiem jest zainstalowanie esbuild jako zależności deweloperskiej.
npm i esbuild -D
Utwórz plik w katalogu głównym swojego projektu lokalnego 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
do uruchamiania esbuild. Otwórz plik package.json i dodaj
tę parę klucz-wartość do obiektu "scripts".
"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 optymalizowaniu esbuild pod kątem środowiska produkcyjnego znajdziesz w oficjalnej dokumentacji dotyczącej minifikacji i innych optymalizacji.