VorwortEs gibt ein Szenario, in dem der Client lange ausgeführt wird, die Rechtsabteilung und die Datenabteilung jedoch einige Informationen von Benutzern sammeln müssen. Nachdem diese Informationen gesammelt wurden, müssen sie entsprechend verarbeitet und dann an den Server gemeldet werden. Der Client stellt eine reine JS-Ausführungs-Engine bereit und erfordert keinen WebView-Container. iOS verfügt über den ausgereiften JavaScriptCore und Android kann die V8-Engine verwenden. Eine solche Engine ist mit einem SDK ausgestattet, das auf die Basisfunktionen und Datenverarbeitungsfähigkeiten von Native zugreift. Es kann als kastrierte Version des Hybrid SDK mit zusätzlichen Datenverarbeitungsfähigkeiten angesehen werden. Ist das Problem behoben? Bei der Verarbeitungslogik werden außerdem zwei Bibliotheken benötigt: Cheerio und SQL. Da es sich ausschließlich um Node-Projekte handelt, können sie nicht direkt in einer reinen JS-Umgebung ausgeführt werden. Daher hat sich die Anforderung geändert: Verpackung des Node-Projekts in die UMD-Spezifikation. Auf diese Weise kann es in einer reinen JS-Umgebung ausgeführt werden. Der folgende Artikel analysiert die verschiedenen Spezifikationen. Tatsächlich sind dies nur einige Spezifikationen für die Front-End-Modularisierung. Der Wert der modularen Front-End-EntwicklungMit der rasanten Entwicklung des Internets wird die Front-End-Entwicklung immer komplexer. Dieser Artikel geht von den in tatsächlichen Projekten aufgetretenen Problemen aus, beschreibt, welche Probleme durch Modularisierung gelöst werden können, und erläutert am Beispiel von Sea.js, wie die modulare Entwicklung des Front-Ends durchgeführt wird. Ärgerliche NamenskonflikteWir beginnen mit einer einfachen Gewohnheit. Wenn ich an einem Projekt arbeite, abstrahiere ich häufig einige allgemeine, Low-Level-Funktionen und trenne sie in separate Funktionen, wie zum Beispiel Funktion jedes(arr) { // Implementierungscode} Funktion log(str) { // Implementierungscode} Ich habe diese Codes extrahiert, sie in util.js vereinheitlicht und die Datei bei Bedarf importiert. Es sah großartig aus und meine Kollegen im Team waren mir sehr dankbar, dass ich ihnen ein so praktisches Toolkit zur Verfügung gestellt habe. Bis das Team größer wurde und die Leute anfingen, sich zu beschweren Xiao Yang: Ich habe eine each-Methode definiert, um über Objekte zu iterieren, aber in util.js gibt es bereits eine each-Methode. Ich muss den Methodennamen jedes Mal ändern, daher kann ich sie nur eachObject-Methode nennen. <br>Zhang San: Ich habe eine Log-Methode definiert, aber es gibt ein Problem mit Wang Wus Code. Wer kann sich das mal ansehen? Es gab immer mehr Beschwerden und schließlich verwiesen wir auf den Java-Ansatz und führten Namespaces ein, um das Problem zu lösen. Der util.js-Code wird also var org = {}; org.Utils = {}; org.Utils.each = Funktion (arr) { // Implementierungscode}; org.Utils.log = Funktion (str) { // Implementierungscode}; Der Code mag zwar sehr einfach aussehen, aber der eigentliche Verfechter des Namespace im Front-End-Bereich ist Yahoo! YUI2-Projekt, sehen Sie sich den Code unten an, ist Yahoo! Ein Open-Source-Projekt wenn (org.cometd.Utils.isString(Antwort)) { gibt org.cometd.JSON.fromJSON(Antwort) zurück; } wenn (org.cometd.Utils.isArray(Antwort)) { Antwort zurückgeben; } Obwohl Namespaces das Konfliktproblem größtenteils lösen können, muss bei jedem Aufruf einer Methode eine Menge Namespace-bezogener Code geschrieben werden, was den Spaß am Programmieren verdirbt. Eine andere Möglichkeit hierfür ist eine selbstausführende Funktion. (Funktion (Argumente) { //... })(Das); Umständliche DateiabhängigkeitenUm mit dem obigen Szenario fortzufahren: In vielen Fällen ist es notwendig, gemeinsame Komponenten auf der UI-Ebene zu entwickeln, damit das Projektteam das Rad nicht neu erfinden muss. Eine der am häufigsten verwendeten Komponenten ist dialog.js <script src="util.js"></script> <script src="dialog.js"></script> <Skript> org.Dialog.init({ /* Konfiguration übergeben */ }); </Skript> Obwohl die öffentliche Gruppe Nutzungsdokumente schreibt und E-Mails sendet, um alle Mitglieder zu informieren (Projektadresse, Nutzung usw.), fragen einige Leute immer noch: „Warum gibt es ein Problem mit dialog.js?“ Das Endergebnis der Untersuchung ist im Wesentlichen, dass util.js nicht eingeführt wird <script src="dialog.js"></script> <Skript> org.Dialog.init({ /* Konfiguration übergeben */ }); </Skript> Namenskonflikte und Dateiabhängigkeiten sind zwei klassische Probleme bei der Front-End-Entwicklung. Nach kontinuierlichem Nachdenken und Forschen der Entwickler sind modulare Lösungen entstanden. Nehmen wir CMD als Beispiel. definieren(Funktion(erfordern, Exporte) { exports.each = Funktion (Array) { // ... }; exports.log = Funktion(Nachricht) { // ... }; }); Durch Exporte können Sie eine Schnittstelle zur Außenwelt bereitstellen. Der dialog.js-Code wird definieren(Funktion(erfordern, Exporte) { var util = erfordern('./util.js') exports.init = Funktion () { // ... }; }); Wenn Sie es verwenden, können Sie die durch Exporte in util.js verfügbar gemachte Schnittstelle über require('./util.js') abrufen. Die require-Methode hat Lösungen in vielen anderen Sprachen: include, Die Vorteile der Modularität1. Modulversionsverwaltung: Durch Konfigurationen wie Aliase und mit Build-Tools kann die Modulversionsverwaltung einfach erreicht werden 2. Verbesserte Wartbarkeit: Durch die Modularisierung kann eine einzelne Verantwortung für jede Datei erreicht werden, was für die Code-Wartung sehr vorteilhaft ist. 3. Optimierung der Front-End-Leistung: Bei der Front-End-Entwicklung ist das asynchrone Laden von Modulen für die Seitenleistung sehr vorteilhaft. 4. Module umgebungsübergreifend teilen: Die CMD-Moduldefinitionsspezifikation ist der NodeJS-Modulspezifikation sehr ähnlich, sodass Sie über die NodeJS-Version von Sea.JS Module problemlos server- und browserübergreifend teilen können. CommonJS-SpezifikationCommonJS ist eine Spezifikation für serverseitige Module. NodeJS übernimmt diese Spezifikation. CommonJS lädt Module synchron, sodass nachfolgende Vorgänge erst nach Abschluss des Ladevorgangs ausgeführt werden können. Aufgrund der Eigenschaften des Servers werden die geladenen Moduldateien im Allgemeinen auf der lokalen Festplatte gespeichert, sodass sie schnell geladen werden, ohne asynchrone Methoden zu berücksichtigen. In der modularen Spezifikation von CommonJS ist jede Datei ein Modul mit unabhängigem Bereich, Variablen und Methoden, das für andere Module unsichtbar ist. Die CommonJS-Spezifikation legt fest, dass innerhalb jedes Moduls die Modulvariable das aktuelle Modul darstellt. Es ist ein Objekt und sein Exportattribut ist die externe Schnittstelle. Um ein Modul zu laden, laden Sie eigentlich das module.exports-Attribut des Moduls. Zum Laden des Moduls wird die require-Methode verwendet. // Person.js Funktion Person () { dies.essen = Funktion () { console.log('etwas essen') } dies.sleep = Funktion () { console.log('schlafen') } } var person = neue Person(); exporte.person = person; exporte.name = Name; // index.js lass person = erfordern('./Person').person; person.essen() Unterschiede zwischen CommonJS- und ES6-Modulen1. CommonJS-Module geben Kopien von Werten aus, während ES6-Module Referenzen auf Werte ausgeben 2. CommonJS-Module werden zur Laufzeit geladen, während ES6-Module zur Kompilierungszeit Ausgabeschnittstellen sind CommonJS-Module exportieren ein Objekt (Eigenschaft module.exports), das erst nach Ausführung des Skripts generiert wird. Der Modulmechanismus von ES6 besteht darin, dass die JS-Engine bei der statischen Analyse des Skripts eine schreibgeschützte Referenz generiert, wenn sie auf den Import des Modulladebefehls stößt. Wenn das Skript tatsächlich ausgeführt wird, verwendet es diese schreibgeschützte Referenz, um den Wert aus dem geladenen Modul abzurufen. AMD-SpezifikationenAMD (Asynchronous Module Definition) ist die standardisierte Ausgabe der Moduldefinition im Prozess der Förderung von Require.JS. AMD befürwortet Front-End-Abhängigkeit. Es handelt sich um eine Obermenge der CommonJS-Modularisierungsspezifikation, die auf Browsern funktioniert. Seine Funktion ist asynchron, wodurch die Parallelitätsfunktionen des Browsers ausgenutzt werden, um die Blockierung von Modulabhängigkeiten zu reduzieren. AMD-API definieren(ID?, Abhängigkeiten?, Fabrik); id ist der Name des Moduls und ein optionaler Parameter. dependencies gibt die Liste der Module an, von denen das Modul abhängt. Es handelt sich um ein Array und einen optionalen Parameter. Die Ausgabe jedes abhängigen Moduls wird wiederum als Parameter an die Fabrik übergeben. erfordern([Modul], Rückruf) Die AMD-Spezifikation ermöglicht, dass das Ausgabemodul mit der CommonJS-Spezifikation kompatibel ist. In diesem Fall lautet die Definitionsmethode wie folgt: definieren(['Modul1', 'Modul2'], Funktion(Modul1, Modul2) { Funktion foo () { // ... } zurück { foo: foo }; }); definieren(Funktion(erfordern, Exporte, Modul) { var angefordertesModul1 = erfordern('./Modul1') var angefordertesModul2 = erfordern('./module2') Funktion foo () { // ... } zurück { foo: foo }; }); Vorteile: Geeignet zum Laden von Modulen in einer Browserumgebung und kann mehrere Module parallel laden Nachteile: Erhöht die Entwicklungskosten, kann nicht bei Bedarf geladen werden, lädt aber alle Abhängigkeiten im Voraus CMD-SpezifikationCMD ist die standardisierte Ausgabe der Moduldefinition im Prozess der Sea.JS-Förderung. CMD plädiert dafür, auf Nähe zu setzen. Die CMD-Spezifikation ist so einfach wie möglich gehalten und mit dem Modul in der CommonJS-Spezifikation kompatibel. Module, die mit der CMD-Spezifikation geschrieben wurden, können in NodeJS ausgeführt werden. CMD-Moduldefinitionsspezifikation Wenn in CMD die erforderliche Abhängigkeitsbeschreibung ein Array verwendet, wird es asynchron geladen. Wenn eine einzelne Abhängigkeit einen String verwendet, wird sie synchron geladen. AMD ist die standardisierte Ausgabe der Moduldefinition während der Förderung von RequireJS und CMD wird während der Förderung von SeaJS allgemein anerkannt. SeaJS stammt von Ant Financial YuBo in China. Über den Unterschied zwischen beiden sagte Yu Bo im Jahr 2012: RequireJS und SeaJS sind beide sehr gute Modullader. Die Unterschiede zwischen ihnen sind wie folgt:
UMD-SpezifikationUMD (Universal Module Definition) wurde mit dem Trend zu großen Front-Ends erstellt, in der Hoffnung, eine plattformübergreifende Lösung für Front-End und Back-End bereitzustellen (unterstützt AMD-, CMD- und CommonJS-Modulmethoden). Umsetzungsprinzip: 1. Stellen Sie zunächst fest, ob das Node.js-Modulformat unterstützt wird (ob Exporte vorhanden sind). Wenn ja, verwenden Sie das Node.js-Modulformat 2. Stellen Sie fest, ob das AMD-Modulformat unterstützt wird (define existiert). Wenn ja, verwenden Sie das AMD-Modulformat. 3. Wenn die ersten beiden nicht vorhanden sind, machen Sie das Modul global öffentlich (Fenster oder global). // Wenn das Modul keine Abhängigkeiten hat, kann das obige Muster vereinfacht werden zu (Funktion (Wurzel, Fabrik) { wenn (Typ der Definition === 'Funktion' und definieren.amd) { // AMD. Als anonymes Modul registrieren. definieren([], Fabrik); } sonst wenn (Typ der Exporte === 'Objekt') { // Node. Funktioniert nicht mit striktem CommonJS, aber // nur CommonJS-ähnliche Umgebungen, die module.exports unterstützen, // wie Node. modul.exporte = fabrik(); } anders { // Browser-Globale (Root ist Fenster) root.returnExports = Fabrik(); } }(diese, Funktion () { // Geben Sie einfach einen Wert zurück, um den Modulexport zu definieren. // Dieses Beispiel gibt ein Objekt zurück, aber das Modul // kann eine Funktion als exportierten Wert zurückgeben. zurückkehren {}; })); Manche Leute fragen sich vielleicht, warum im obigen Urteil AMD steht, aber kein CMD? Da das Frontend-Building-Tool Webpack die CMD-Spezifikation nicht erkennt, erfordert die Verwendung von CMD die Referenzierung von Tools wie Sea.JS. Mal ehrlich: Wenn Sie CMD beurteilen wollen, wie schreiben Sie den UMD-Code? (Funktion(Wurzel, Fabrik) { wenn (Typ der Definition === 'Funktion' und definieren.amd) { // AMD. Als anonymes Modul registrieren. definieren([], Fabrik); } sonst wenn (Typ der Definition === 'Funktion' und define.cmd) { //CMD definieren(Funktion(erfordern, Exporte, Modul) { modul.exporte = fabrik() }) } sonst wenn (Typ der Exporte === 'Objekt') { // Node. Funktioniert nicht mit striktem CommonJS, aber // nur CommonJS-ähnliche Umgebungen, die module.exports unterstützen, // wie Node. modul.exporte = fabrik(); } anders { // Browser-Globale (Root ist Fenster) root.returnExports = Fabrik(); } }(diese, Funktion() { // Geben Sie einfach einen Wert zurück, um den Modulexport zu definieren. // Dieses Beispiel gibt ein Objekt zurück, aber das Modul // kann eine Funktion als exportierten Wert zurückgeben. zurückkehren {}; })) Zurück zum ThemaWie Cheerio in eine normale JS-Ausführungsumgebung gepackt wird. Mithilfe von Webpack können Sie ganz einfach ein UMD-Standardpaket generieren. modul.exporte = { Eintrag: './src/cheerio.js', Ausgabe: { Dateiname: „cheerio.js“, // Export nach AMD, CommonJS oder Windows Bibliotheksziel: 'umd', // der ins Fenster exportierte Name Bibliothek: 'Cheerio', globales Objekt: "dieses" } } ZusammenfassenDer zugrunde liegende Rendering-Kernel von Mobiltelefonen (egal ob iOS oder Android) ähnelt der Chrome v8-Engine. Wenn die v8-Engine JS-Code ausführt, kompiliert sie den Code zunächst mithilfe der Assembly-Bibliothek MacroAssembler im Speicher in Maschinencode und sendet ihn dann zur Ausführung an die CPU. Wie andere JS-Engines führt sie keine zeilenweise Analyse und Ausführung durch. Daher ist die statisch geladene ES6-Modulspezifikation für den V8-Motor hilfreicher, um seinen Wert zu realisieren. Die zur Laufzeit geladenen CommonJS-, AMD- und CMD-Spezifikationen tragen nicht dazu bei, dass die Leistung der V8-Engine gut ausfällt. In NodeJS-Entwicklungsprojekten unterstützt Node9 bereits die ES6-Syntax und kann die ES6-Modulspezifikation vollständig nutzen. Die Geburt von NodeJS basiert auf Googles v8-Engine. Es gibt keinen Grund, das maximale Potenzial von v8 nicht zu berücksichtigen. In Browser-JS-Entwicklungsprojekten ist die Verwendung der CommonJS-Spezifikation definitiv nicht geeignet, da das Laden von Dateien vom Server einige Zeit in Anspruch nimmt. Ob die native ES-Modulspezifikation oder Sea.js verwendet wird, hängt vom jeweiligen Szenario ab. Wenn die Seite möglichst schnell geladen werden soll, eignet sich Sea.js, handelt es sich um eine einseitige Website, empfiehlt sich die Verwendung der nativen ES6-Modulspezifikation. Ein weiterer Punkt ist, dass Chrome nicht der einzige Browser ist. Für Browser, die die v8-Engine nicht verwenden, wird der Vorteil der Verwendung der nativen ES6-Spezifikation etwas reduziert. Oben finden Sie eine kurze Erläuterung der Details mehrerer Spezifikationen für die JS-Frontend-Modularisierung. Weitere Informationen zur JS-Frontend-Modularisierung finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Detaillierte Erläuterung der Nginx-Weiterleitungssocket-Portkonfiguration
>>: Mysql-Optimierungstechniken zum Abfragen von Daten basierend auf der Zeit
Ich habe das von Alibaba Cloud gekaufte CentOS fü...
Übernahme des Geschäfts: Sehen Sie sich die Gehal...
Was ist ein Primärschlüssel? Ein Primärschlüssel ...
Inhaltsverzeichnis 1. Analyse der MySQL-Architekt...
Inhaltsverzeichnis Vorwort Globale Sperre Tabelle...
sort Den Inhalt einer Textdatei sortieren Verwend...
Inhaltsverzeichnis Hintergrund analysieren Datens...
Mobile Mobile Seiten müssen nur mit Chrome und Sa...
Inhaltsverzeichnis 1. Mit der MySQL-Replikation v...
Inhaltsverzeichnis Einführung in FRM-Dateien und ...
Inhaltsverzeichnis Zusammenfassen Zusammenfassen ...
Inhaltsverzeichnis Frage Hintergrund Idee & U...
Inhaltsverzeichnis 1. Überprüfen Sie, ob die Dock...
Wir hoffen, dass dieser Artikel durch eine verglei...
Einfach ausgedrückt bedeutet src „Ich möchte dies...