Einleitung
Eine der heute am häufigsten verwendeten JavaScript-Bibliotheken ist RequireJS. Jedes Projekt, an dem ich in letzter Zeit beteiligt war, hat RequireJS verwendet, oder ich habe empfohlen, RequireJS hinzuzufügen. In diesem Artikel beschreibe ich, was RequireJS ist und einige seiner grundlegenden Szenarien.
Asynchrone Moduldefinition (AMD)
Wenn man über RequireJS spricht, kommt man nicht umhin zu erwähnen, was JavaScript-Module sind und was AMD ist.
JavaScript-Module sind lediglich Codeausschnitte, die dem SRP (Single Responsibility Principle) folgen und eine öffentliche API offenlegen. In der modernen JavaScript-Entwicklung können Sie viele Funktionen in Modulen kapseln, und in den meisten Projekten verfügt jedes Modul über eine eigene Datei. Dies macht JavaScript-Entwicklern das Leben etwas schwer, da sie ständig auf die Abhängigkeiten zwischen Modulen achten und diese Module in einer bestimmten Reihenfolge laden müssen, da die Laufzeit sonst Fehler auslöst.
Das Skript-Tag wird verwendet, wenn Sie ein JavaScript-Modul laden möchten. Um abhängige Module zu laden, müssen Sie zuerst das abhängige Modul und dann das abhängige Modul laden. Wenn Sie Skript-Tags verwenden, müssen Sie deren Laden in dieser bestimmten Reihenfolge anordnen, damit die Skripts synchron geladen werden. Sie können die Schlüsselwörter „async“ und „defer“ verwenden, um den Ladevorgang asynchron zu gestalten. Allerdings kann es sein, dass Sie während des Ladevorgangs die Ladereihenfolge verlieren. Eine andere Möglichkeit besteht darin, alle Skripte zu bündeln, Sie müssen sie jedoch beim Bündeln trotzdem in der richtigen Reihenfolge sortieren.
AMD ist eine solche Definition eines Moduls, sodass das Modul und seine Abhängigkeiten asynchron, aber in der richtigen Reihenfolge geladen werden können.
CommonJS ist ein Versuch, gängige JavaScript-Muster zu standardisieren. Es enthält die AMD-Definition, die ich Ihnen empfehle, bevor Sie mit diesem Artikel fortfahren. In ECMAScript 6, der nächsten Version der JavaScript-Spezifikation, gibt es Spezifikationsdefinitionen für Ausgabe, Eingabe und Module, die Teil der JavaScript-Sprache werden, und das wird nicht lange dauern. Das möchten wir auch über RequireJS sagen.
ErforderlichJS?
RequireJS ist ein Javascript-Datei- und Modul-Framework, das von http://requirejs.org/ oder über Nuget heruntergeladen werden kann, wenn Sie Visual Studio verwenden. Es unterstützt Browser- und Serverumgebungen wie node.js. Mit RequireJS können Sie nacheinander nur die relevanten abhängigen Module lesen.
Wenn Sie das Skript-Tag zum Laden der von Ihnen definierten Abhängigkeiten verwenden, lädt RequireJS diese Abhängigkeiten über die Funktion head.appendChild(). Wenn Abhängigkeiten geladen werden, berechnet RequireJS die Reihenfolge der Moduldefinitionen und ruft sie in der richtigen Reihenfolge auf. Das bedeutet, dass Sie lediglich ein „Root“ verwenden müssen, um alle benötigten Funktionen zu lesen, und RequireJS erledigt den Rest. Um diese Funktionen korrekt nutzen zu können, müssen alle von Ihnen definierten Module die RequireJS-API verwenden, da sie sonst nicht wie erwartet funktionieren.
Die RequireJS-API existiert unter dem Namespace requirejs, der beim Laden von RequireJS erstellt wird. Seine Haupt-API besteht hauptsächlich aus den folgenden drei Funktionen:
Später zeigen wir Ihnen, wie Sie diese Funktionen verwenden. Lassen Sie uns jedoch zunächst den Ladevorgang von RequireJS verstehen.
Datenhauptattribut
Nachdem Sie RequireJS heruntergeladen haben, müssen Sie zunächst verstehen, wie RequireJS zu funktionieren beginnt. Wenn RequireJS geladen wird, wird das data-main-Attribut verwendet, um nach einer Skriptdatei zu suchen (es sollte dasselbe Skript sein, das RequireJS mit src geladen hat). data-main muss einen Root-Pfad für alle Skriptdateien festlegen. Basierend auf diesem Root-Pfad lädt RequireJS alle zugehörigen Module. Das folgende Skript ist ein Beispiel für die Verwendung von data-main:
Eine andere Möglichkeit, den Root-Pfad zu definieren, ist die Verwendung von Konfigurationsfunktionen, wie wir später sehen werden. requireJs geht davon aus, dass alle Abhängigkeiten Skripte sind, sodass Sie beim Deklarieren einer Skriptabhängigkeit nicht das Suffix .js verwenden müssen.
Konfigurationsfunktion
Wenn Sie die Standardkonfiguration von RequireJS ändern möchten, um Ihre eigene Konfiguration zu verwenden, können Sie die Funktion require.configh verwenden. Die Konfigurationsfunktion muss ein optionales Parameterobjekt übergeben, das viele Konfigurationsparameteroptionen enthält. Hier sind einige Konfigurationen, die Sie verwenden können:
Hier ist ein Beispiel für die Verwendung der Konfiguration:
require.config({ //By default load any module IDs from scripts/app baseUrl: 'scripts/app', //except, if the module ID starts with "lib" paths: { lib: '../lib' }, // load backbone as a shim shim: { 'backbone': { //The underscore script dependency should be loaded before loading backbone.js deps: ['underscore'], // use the global 'Backbone' as the module name. exports: 'Backbone' } } });
In diesem Beispiel ist der Root-Pfad auf „scripts/app“ festgelegt. Jedes Modul, das mit „lib“ beginnt, wird im Ordner „scripts/lib“ konfiguriert und lädt eine Shim-Abhängigkeit.
Module mit RequireJS definieren
Module sind Objekte mit interner Implementierungskapselung, offengelegten Schnittstellen und angemessen begrenztem Umfang. ReuqireJS stellt die Definitionsfunktion zum Definieren von Modulen bereit. Konventionell sollte nur ein Modul pro Javascript-Datei definiert werden. Die Definitionsfunktion akzeptiert ein Abhängigkeitsarray und eine Funktion, die die Moduldefinition enthält. Normalerweise empfängt die Moduldefinitionsfunktion die abhängigen Module im vorherigen Array der Reihe nach als Parameter. Hier ist zum Beispiel eine einfache Moduldefinition:
define(["logger"], function(logger) { return { firstName: “John", lastName: “Black“, sayHello: function () { logger.log(‘hello'); } } } );
Wir sehen, dass ein Modulabhängigkeitsarray mit Logger an die Definitionsfunktion übergeben wird und das Modul später aufgerufen wird. Ebenso sehen wir, dass es im definierten Modul einen Parameter namens Logger gibt, der auf das Logger-Modul gesetzt wird. Jedes Modul sollte seine API zurückgeben. In diesem Beispiel haben wir zwei Eigenschaften (firstName und lastName) und eine Funktion (sayHello). Solange das Modul, das Sie später definieren, über die ID auf dieses Modul verweist, können Sie dann dessen verfügbar gemachte API verwenden.
Verwenden Sie die Anforderungsfunktion
Eine weitere sehr nützliche Funktion in RequireJS ist die Require-Funktion. Die Funktion „require“ wird zum Laden von Modulabhängigkeiten verwendet, erstellt jedoch kein Modul. Beispiel: Für die folgenden Verwendungszwecke muss eine Funktion definiert werden, die jQuery verwenden kann.
require(['jquery'], function ($) { //jQuery was loaded and can be used now });
Zusammenfassung
In diesem Artikel habe ich die RequireJS-Bibliothek vorgestellt, eine der Bibliotheksfunktionen, die ich zum Erstellen jedes Javascript-Projekts verwende. Es wird nicht nur zum Laden von Modulabhängigkeiten und zugehörigen Befehlen verwendet, RequireJS hilft uns auch beim Schreiben modularen JavaScript-Codes, was sich sehr positiv auf die Skalierbarkeit und Wiederverwendbarkeit des Codes auswirkt.