Heim >Web-Frontend >js-Tutorial >Modulare JavaScript-Entwicklungsbibliothek SeaJS
SeaJS, eine modulare JavaScript-Entwicklungsbibliothek
SeaJS wurde von Lifesinger, einem einheimischen Genie, entwickelt. Die aktuelle Version ist 1.1.1, der Quellcode umfasst weniger als 1500 Zeilen, ist auf 4 KB komprimiert und die Qualität ist extrem hoch.
In diesem Artikel wird auf einige grundlegende Verwendungszwecke von SeaJS eingegangen. Er wird nicht alles abdecken, aber er wird auf einige Details eingehen, die nach meinem persönlichen Verständnis nicht in den offiziellen Dokumenten erwähnt werden.
1. Globale Schnittstelle von SeaJS
SeaJS stellt der Welt zwei Bezeichner zur Verfügung: seajs und define.
Wenn Sie den Bezeichner seajs bereits in Ihrem Projekt verwendet haben und ihn nicht ändern möchten. Zu diesem Zeitpunkt kann SeaJS die globalen Seajs aufgeben. Beispiel:
var boot = seajs.noConflict();
Zu diesem Zeitpunkt entspricht Boot den vorherigen Seajs.
Wenn Sie die Bezeichnerdefinition überhaupt in Ihrem Projekt verwenden, möchten Sie sie nicht ändern. SeaJS ist sehr tolerant und seine Definition kann auch weitergegeben werden. Beispielsweise übergibt
var boot = seajs.noConflict(true);
nur einen Wert mehr als oben. Zu diesem Zeitpunkt ist die globale Definition nicht mehr vorhanden. Zu diesem Zeitpunkt muss boot.define verwendet werden, um die vorherige Definition zu ersetzen.
Studenten, die jQuery verwendet haben, sollten mit der Methode „noConflict“ von SeaJS vertraut sein.
2. So schreiben Sie Module in SeaJS
SeaJS verwendet standardmäßig die globale Definitionsfunktion (define kann als Syntaxschlüsselwort betrachtet werden: id, Deps und Fabrik.
define(id?, deps?, Factory);
Diese Definition kann Sie leicht an AMDs einzige API erinnern: Funktion „Definieren“. Mit anderen Worten: Es ist verwirrend und führt zu einer Verwechslung zwischen der Definition von SeaJS und RequireJS.
Sie haben alle eine globale Definition mit drei formalen Parametern, und die entsprechenden formalen Parameternamen sind auch gleich. Es wäre falsch, wenn SeaJS eine Implementierung von AMD wäre.
Tatsächlich sind die ersten beiden Parameter von define in SeaJS und RequireJS tatsächlich gleich.
IDs sind alle Zeichenfolgen und folgen den Modulkennungen. Deps beziehen sich alle auf abhängige Module und ihre Typen sind Arrays. Der einzige Unterschied liegt im dritten Parameter Factory. Obwohl es sich bei den Typen auch um Funktionen handelt, ist die Bedeutung der Factory-Parameter unterschiedlich.
Es gibt zwei Fälle von Factory-Parametern in RequireJS:
a- und deps-(Array-)Elemente entsprechen eins zu eins. Das heißt, es gibt mehrere Deps und mehrere tatsächliche Parameter der Fabrik.
define(['a', 'b'], function(a, b){
// todo
});
b. Module/Wrapping-Format).
define(function(require, exports, module){
// todo
});
Diese Methode ist ein späterer Kompromiss von RequireJS zu Modules/Wrappings, das heißt, sie ist es damit kompatibel. Die Definition von SeaJS unterstützt nur die zweite Schreibweise von RequireJS: Modules/Wrappings.
Hinweis: SeaJS folgt Modules/Wrappings und Modules/1.1.1. In diesen beiden Spezifikationen wird das Schlüsselwort „define“ nicht erwähnt. „Module/Wrapping“ erfordert, dass Module mithilfe von module.declare anstelle von „define“ definiert werden. Allerdings gibt es nur in der AMD-Spezifikation die Definition von define. Das heißt, obwohl SeaJS keine Implementierung von AMD ist, verwendet es den Identifier define, der extrem leicht missverstanden werden kann.
Nachdem ich so viel gesagt habe, habe ich noch nicht mit dem Schreiben eines Moduls begonnen. Beginnen wir mit dem einfachsten
1. Einfaches Modul
define({
addEvent: function(el, type, fn){},
removeEvent: function(el, type, fn){ } ,
fireEvent: function(el, type){}
});
Auf diese Weise wird ein Ereignismodul geschrieben, das sich nicht vom Schreiben eines Singletons unterscheidet. Diese Methode wird häufiger zur Definition reiner Datenmodule verwendet. Es ähnelt
var E = {
addEvent: function(el, type, fn){},
removeEvent: function(el, type, fn){},
fireEvent: function( el , Typ){}
};
2. Einfaches Verpackungsmodul
define(function() {
// Einige interne Hilfsfunktionen
// ...
function addEvent() {
}
function removeEvent() {
}
function fireEvent() {
// .
}
return {
. In dieser anonymen Funktion können Sie viele Dinge tun. Zum Schluss legen Sie einfach die erforderlichen Schnittstellen frei. Es ähnelt
var E = function() {
// Einige interne Hilfsfunktionen
// ...
function addEvent() {
}
function removeEvent() {
}
function fireEvent() {
}
return {
addEvent: addEvent,
RemoveEvent: RemoveEvent,
FireEvent: FireEvent
};
}();
3. Verpackungsmodul im NodeJS-Stil
Die beiden oben genannten In dieser Schreibmethode gibt es keine Spur des NodeJS-Stils (Module/1.1.1). Schreiben Sie ihn als Äquivalent zu „Methode 2“ um.
define(function(require, exports) {
// Einige interne Hilfsfunktionen
// ...
function addEvent() {
}
function removeEvent() { exports.addEvent = fireEvent;
});
Sie können den Unterschied zu „Methode 2“ sehen. Er liegt in:
1: Die anonyme Funktion hat zwei Parameter require und exports.
2: Die Exportschnittstelle gibt kein Objekt zurück, sondern verwendet Exporte.
Sind Exporte nicht genau der Stil von NodeJS? Aufmerksame Schüler stellen möglicherweise fest, dass der Parameter „require“ in diesem Beispiel nicht verwendet wird, worauf weiter unten eingegangen wird.
4. Module mit Abhängigkeiten
„Abhängigkeiten“ in SeaJS müssen mit der Funktion „require“ abgerufen werden. Obwohl der zweite Parameter deps von SeaJS auch „Abhängigkeit“ bedeutet, ist dies üblich Bereitstellung von Verpackungstools (SPM). Darüber hinaus wird die Anforderung von SeaJS als Parameter an die anonyme Funktion übergeben, und die Anforderung von RequireJS ist eine globale Variable. www.2cto.com
Die obige Definition ist ein Modul ohne Abhängigkeiten, und die folgenden sind Module mit Abhängigkeiten.
define(function(require, exports) {
var cache = require('cache');
// ...
exports.bind = bind;
exports.unbind = unbind;
exports.trigger = trigger;
});
Dieses Ereignismodul hängt vom Cache-Modul ab und die Funktion verfügt über zwei formale Parameter require und exports. Abgesehen von den äußeren anonymen Funktionen und der Definition handelt es sich um das Standardformat von NodeJS: Verwenden Sie die Funktion „require“, um abhängige Module abzurufen, und verwenden Sie „exports“, um vorhandene Modulschnittstellen zu exportieren.
Tatsächlich müssen Module mit Abhängigkeiten in SeaJS gemäß „Methode 4“ geschrieben werden, das heißt, sie müssen Wrapper-Module sein und der erste Parameter der anonymen Funktion muss der Bezeichner „require“ sein. Das heißt, Sie können require als ursprüngliches Syntaxschlüsselwort verwenden, obwohl es nicht global ist.
Werfen wir einen Blick auf einige interessante Phänomene anonymer Funktionsparameter require und exports
a Wenn Sie etwas anderes als require schreiben, was passiert, wenn Sie es in req ändern?
define(function(req, exports) {
var cache = req('cache');
// ...
exports.bind = bind;
exports.unbind = unbind;
exports.trigger = trigger;
});
Firebug-Netzwerkanforderung lautet wie folgt
Sie werden sehen, dass der abhängige „Cache“ lautet nicht geladen. Natürlich wird JS definitiv einen Fehler melden.
b. Ändern Sie nur den formalen Parameter der anonymen Funktion in req und verwenden Sie weiterhin require innerhalb der Funktion.
define(function(req, exports) {
var cache = require('cache');
exports.bind = bind;
exports.unbind = unbind;
});
Sehen Sie sich die Netzwerkanfrage an
Dieses Mal hat das „Cache“-Modul sie tatsächlich angefordert.
Schauen Sie sich den obigen anonymen Funktionscode genau an, in dem „require“ nicht deklariert ist und der formale Parameter „req“ nicht „require“ ist. Dann
?
1 var cache = require('cache'); Woher kommt das require in
?
Wenn wir uns den SeaJS-Quellcode ansehen, können wir sehen, dass seine Definitionsfunktion den toString der anonymen Funktion übernimmt und den regulären Abgleich verwendet, um den „Cache“ zu analysieren (private parseDependencies-Funktion).
Wir sehen auch, dass, obwohl die Cache-Anfrage abgeschlossen ist, immer noch ein Fehler gemeldet wird, weil „require“ während der Ausführungsphase undefiniert ist. Daher muss beim Schreiben abhängiger Module der erste Parameter der anonymen Funktion erforderlich sein und kann nicht geändert werden.
Da Factory.toString und reguläre Analyseabhängigkeiten verwendet werden, können die Parameter von require keine Ausdrücke sein, wie z. B.
// Die Parameter von require können keine Ausdrucksoperationen sein
require("ui-" + "dialog");
Sie können keine Require-Aliase wie
// verwenden. Sie können Require nicht einer anderen Variablen zuweisen
var req = require;
req("ui-dialog");
c . Exporte in expo ändern
define(function(require, expo) {
var cache = require('cache');
// ...
expo. bind = bind;
expo.unbind = unbind;
expo.trigger = trigger;
});
Es gibt kein Problem beim Ausführen. Das heißt, der zweite Parameter „Exporte“ kann angepasst werden. Offensichtlich ist SeaJS nicht damit einverstanden, „exports“ in etwas anderes zu ändern, was offensichtlich die Modulspezifikation im NodeJS-Stil (Modules/1.1.1) zerstört – sie verwenden „exports“, um die Modulschnittstelle zu exportieren. Dies kann jedoch in SeaJS nicht erzwungen werden, es kann nur eine künstliche Vereinbarung sein.
5. Module mit gemischten Schreibmethoden
Das Obige hat gezeigt, wie man Module in verschiedenen Situationen schreibt. Um mit dem NodeJS-Stil konsistent zu sein: Verwenden Sie require, um „Abhängigkeiten“ zu erhalten, und exports, um „Schnittstellen“ zu exportieren. SeaJS hat Einschränkungen beim Abrufen von Abhängigkeiten, das heißt, require muss verwendet werden. Exporte müssen jedoch nicht verwendet werden, d. h. Exporte können in etwas anderes geändert werden. Sie können den „Rückgabewert“ sogar direkt verwenden.
define(function(require) {
var cache = require('cache');
// ...
// Verwenden Sie den Rückgabewert, um die Schnittstelle zu exportieren
return {
bind: function() {},
unbind: function() {},
fire: function() {}
};
});
Wir wissen, dass ein Modul nur ein Objekt in NodeJS sein kann. Das heißt, hängen Sie Methoden immer an Exporte an. Wenn Sie Exporte verwenden, um die Schnittstelle in SeaJS zu exportieren, gilt das Gleiche, und das Modul kann nur ein JS-Objekt sein. Wenn Sie zum Exportieren der Schnittstelle „Rückgabewert“ verwenden, kann das Modul ein beliebiger JS-Typ sein. Im Folgenden wird ein Funktionstypmodul zurückgegeben.
define(function(require) {
var cache = require('cache');
function ad() {
} //...
}
// Funktionstypmodul
return ad;
});
3. SeaJS-Lademethode
Obwohl es verschiedene Möglichkeiten (synchrones und asynchrones) Laden bietet, Die Am einfachsten ist es, Skript-Tags direkt auf die Seite zu schreiben. Nach der Einführung von SeaJS beginnt man meist mit der Methode seajs.use.
seajs.use hat zwei Parameter. Der erste Parameter kann ein String (Modulname) oder ein Array (mehrere Module) sein. Der zweite Parameter ist die Callback-Funktion. Rückruf nach dem Laden des Moduls. Die Parameter der Callback-Funktion entsprechen eins zu eins dem ersten Parameter.
seajs.use('dom', function(dom) {
// todo with dom
});
Das Dom-Modul wird in der Callback-Funktion wie folgt verwendet. Natürlich bietet es auch die Verknüpfung data-main (wie RequireJS).