codestory

Die Geschichte der Module in JavaScript

View more Tutorials:

Folge uns auf unserer fanpage, um jedes Mal benachrichtigt zu werden, wenn es neue Artikel gibt. Facebook

1- Module?

Dieser Artikel führt Sie in die Modulhistorie in JavaScript ein. Viele Spezifikationen und Modulimplementierungen wurden erstellt, bis JavaScript ES6 (2105) eine neue Modulspezifikation veröffentlichte, die auf Sprachebene unterstützt wurde. Daher werden die alten Spezifikationen langsam obsolet. Einige von ihnen sind zwar noch irgendwo im Einsatz, wie zum Beispiel NodeJS, aber sie werden sicherlich in naher Zukunft auslaufen.
Der Zweck dieses Artikels ist es, einen Überblick zu geben und Verwirrung für diejenigen zu beseitigen, die gerade erst mit dem JavaScript Module beginnen, und zu vermeiden, Zeit mit dem Erlernen veralteter Bibliotheken zu verschwenden.
JavaScript-Programme begannen ziemlich klein – in den frühen Tagen wurden sie hauptsächlich für isolierte Skriptaufgaben verwendet, um Ihren Webseiten bei Bedarf ein wenig Interaktivität zu verleihen, sodass große Skripte im Allgemeinen nicht benötigt wurden. Spulen Sie ein paar Jahre vor und wir haben jetzt komplette Anwendungen, die in Browsern mit viel JavaScript ausgeführt werden, sowie JavaScript, das in vielen verschiedenen Kontexten verwendet wird, wie z. B. NodeJs.
Als JavaScript zunehmend in Anwendungen verwendet wurde, wurde es schwieriger, den Code zu verwalten und zu warten. Darüber hinaus führt die Verwendung mehrerer JavaScript-Dateien im selben Programm zu Konflikten bei Variablen- oder Funktionsnamen und birgt große Risiken. Schauen Sie sich das folgende einfache Beispiel an:
file_1a.js

var friendName = "Tom";
function sayHello() {
    console.log(`Hello ${friendName}!`);
}
file_2a.js

sayHello(); // Hello Tom!
friendName = 'Jerry';
sayHello(); // Hello Jerry!
test_a.html

<html>
  <head>
     <script src="file_1a.js"></script>
     <script src="file_2a.js"></script>
     <script>
        var friendName = 'Donald';
        sayHello(); // Hello Donald!
     </script>
  </head>
  <body>
      View the result in the Browser Console Window.
  </body>
</html>
Output:

Hello Tom!
Hello Jerry!
Hello Donald!
So entstand das Modulkonzept zur Lösung zweier wichtiger Probleme:
  • Das Modul muss ein geschlossener Raum sein, alles, was nach außen geteilt wird, muss einer klaren Absicht entsprungen sein.
  • Module sollten eine Möglichkeit bieten, eine große Anwendung in viele separate kleine Teile zu unterteilen, um Programmierern die Entwicklung und Wartung der Anwendung zu erleichtern.

2- IIFE

IIFE (Immediately Invoked Function Expression): Dies ist die primitivste Technik zur Modularisierung von Code. Zu diesem Zeitpunkt existiert das Konzept von Klassen in JavaScript nicht. Die Verwendung von IIFE gibt uns die Freiheit, Variablen oder Funktionen in einem geschlossenen Raum für den internen Gebrauch zu erstellen, ohne Konflikte an anderer Stelle in der Anwendung befürchten zu müssen.
Der IIFE-Ausdruck sieht folgendermaßen aus:

(function () {
  // Statements
})();
Es sieht aus wie ein Gehirnhack, weil viele Klammern in den Ausdruck einbezogen sind, aber die äquivalente Form unten ist definitiv einfacher zu verstehen:

var myFunc = function()  {
   // Statements
}  
myFunc();
IIFE hilft dabei, den darin verarbeiteten Code zu verbergen und zeigt nur das, was wir wollen. Beispiel:

var text = (function () {
    var privateText = "My private TEXT";
    var publicText = "My public TEXT";
    return publicText;
})();

console.log(text); // My public TEXT
Und wir können immer noch normal auf globale Variablen innerhalb des IIFE zugreifen:

var myGlobalVariable = 'Hello, I am a global variable :)';

var text = (function () {
    var privateText = "My private TEXT";
    var publicText = "My public TEXT";
    console.log(myGlobalVariable);
    return publicText;
})();

console.log(text); // My public TEXT
Um mit der obigen Idee fortzufahren, gibt ein IIFE-Beispiel ein als Interface strukturiertes Objekt zurück:
file_1b.js

var mySimpleModule = (function() {
   var greeting = 'Hello'; // Private variable!
   var friendName = "Tom";
   var sayHello = function()  {
       console.log(`${greeting} ${friendName}!`);
   }
   var mm = {
       friendName: friendName,
       sayHello: sayHello
   };
   return mm;
})();
file_2b.js

// Call sayHello function of 'mySimpleModule':
mySimpleModule.sayHello(); // Hello Tom!

var friendName = 'Donald';
mySimpleModule.friendName = 'Jerry';
mySimpleModule.sayHello(); // Hello Jerry!

3- CommonJS

CommonJS ist eine Spezifikation, die im Januar 2009 vom Mozilla-Ingenieur Kevin Dangoor gestartet wurde. Sein Hauptzweck besteht darin, Modulökosystemkonventionen für andere JavaScript-Umgebungen als die vom Browser bereitgestellten festzulegen. Wir sind jetzt in der Mitte, wie die Abbildung unten zeigt, richtig?
Eigentlich hieß das Projekt ursprünglich ServerJS und zielte auf das JavaScript-Ökosystem auf dem Server ab. Im August 2009 wurde es in CommonJS umbenannt als Ausdruck seiner breiten Einsatzmöglichkeiten, einschließlich Browser.
Seit seiner Einführung wurde die CommonJS-Modulspezifikation für NodeJS verwendet. Und bis zur Veröffentlichung dieses Artikels (2021) wurde CommonJS noch in NodeJS verwendet. Es ist jedoch sicher, dass es in naher Zukunft durch das ES6 Module ersetzt wird. Die identifizierenden Merkmale von CommonJS sind die Funktionen require() und module.exports().
Die Vorteile von CommonJS:
  • Einfach und leicht zu bedienen, ohne auf die Dokumentation zu schauen.
  • Eingebauter Abhängigkeitsmanager. Module werden in einer geeigneten Reihenfolge geladen.
  • Die Funktion require() kann überall verwendet werden, um ein anderes Modul anzufordern.
  • Zirkuläre Abhängigkeit unterstützen.
Die Nachteile von CommonJS:
  • Das synchrone Laden von Modulen führt zu einer langsamen Ladegeschwindigkeit und ist für bestimmte Verwendungszwecke, wie z. B. browserseitige Anwendungen, nicht geeignet.
  • Eine Datei pro Modul.
  • Browser verstehen keine Module nach dem CommonJS-Standard. Es benötigt eine zusätzliche Module Loader Bibliothek oder muss zumindest von einem transpiler transpiliert werden.
  • Unterstützt keine Konstruktorfunktionen (als Spezifikation). NodeJS unterstützt dies jedoch.
  • Es ist schwierig, statische Codeparser schwierig zu analysieren.
JavaScript-Bibliotheken, die die CommonJS-Spezifikation implementieren:
  • NodeJS (Server side)
  • webpack (Client side)
  • Browserify (Client side)
Beispiel: So deklarieren Sie ein Modul in CommonJS:
cjs_file_1.js

function _add(a, b) {
    return a + b;
}
function _subtract(a, b) {
    return a - b;
}
module.exports = {
    add: _add,
    subtract: _subtract,
};
Die Verwendung:
cjs_file_2.js

// Using require() function to load file "csj_file_1.js", no need .js extension.
var calculator = require("./csj_file_1");
console.log(calculator.add(2, 2)); // 4
console.log(calculator.subtract(2, 2)); // 0
Sehen Sie  ausführliche CommonJS-Artikel:

4- AMD

AMD (Asynchronous Module Definition) wurde aus einer Gruppe von Entwicklern geboren, die mit der von CommonJS eingeschlagenen Richtung unzufrieden waren. Tatsächlich wurde AMD schon früh in seiner Entwicklung von CommonJS getrennt. Der Hauptunterschied zwischen AMD und CommonJS liegt in der Unterstützung des asynchronen Ladens von Modulen. Wie CommonJS ist AMD nur eine Spezifikation.
Beim asynchronen Laden können Bibliotheken, die beim Laden nicht voneinander abhängig sind, gleichzeitig geladen werden. Dies ist besonders wichtig für Browser, bei denen die Startzeit für eine gute Benutzererfahrung von entscheidender Bedeutung ist.
Die Vorteile von AMD:
  • Asynchrones Laden, bessere Startzeit.
  • Unterstützt und ist kompatibel mit den Funktionen require() und module.exports(), ähnlich wie CommonJS.
  • Eingebauter Abhängigkeitsmanager.
  • Ein Modul kann mehrere Dateien enthalten.
  • Konstruktorfunktion unterstützen.
  • Zirkuläre Abhängigkeit unterstützen.
  • Plugin-Unterstützung (benutzerdefinierte Ladeschritte).
Die Nachteile von AMD:
  • Syntaktisch ist es etwas komplizierter als CommonJS.
  • Es ist schwierig, statische Codeparser zu analysieren.
  • Browser verstehen keine Module nach AMD-Standards. Es benötigt eine zusätzliche Module Loader Bibliothek oder muss zumindest von einem transpiler transpiliert werden.
Z.B: Ein AMD erstellen:
amd_file_1.js

define("myAmdModule", {
    add: function (a, b) {
        return a + b;
    },
    subtract: function (a, b) {
        return a - b;
    },
});
amd_file_2.js

require(["myAmdModule"], function (myAmdModule) {
    console.log(myAmdModule.add(2, 2)); // 4
    console.log(myAmdModule.subtract(2, 2)); // 0
});
Sehen Sie  ausführliche AMD-Artikel:

5- UMD

UMD (Universal Module Definition) ist eine Reihe von Techniken zum Erstellen von Modulen, die als IIFE-, CommonJS- oder AMD-Module importiert werden können. Daher kann ein Programm jetzt Module von Drittanbietern importieren, unabhängig davon, welche Modulspezifikation es verwendet.
zum Beispiel:
UMD_file_1.js

(function (myUmdModule) {
    if (typeof define === 'function' && define.amd) {
        // Export with AMD
        define("myUmdModule", myUmdModule);
    } else if (typeof module === 'object' && module.exports) {
        // Export with CommonJS
        module.exports = myUmdModule;
    } else {
        // Export with browser global
        window.myUmdModule = myUmdModule;
    }
}({
    add: function (a, b) {
        return a + b;
    },
    subtract: function (a, b) {
        return a - b;
    },
}));
UMD_file_2.js

// Load with AMD
require(["myUmdModule"], function (myUmdModule) {
    console.log(myUmdModule.add(2, 2));
    console.log(myUmdModule.subtract(2, 2));
});
// Load with CommonJS
var myUmdModule = require("./myUmdModule");
console.log(myUmdModule.add(2, 2));
console.log(myUmdModule.subtract(2, 2));

6- ES Modules

ES Modules, auch bekannt als ECMAScript Modules oder ES6 Modules oder ES2015 Modules. ES Modules ist die Lösung für eine glänzende Zukunft des Modul-Ökosystems, indem es die Syntax der Moduldeklaration standardisiert, sowohl am Backend als auch am Frontend arbeitet und von JavaScript auf Sprachebene unterstützt wird. Allerdings sind nicht alle Benutzer auf moderne Browser umgestiegen, die ES6 unterstützen, daher dauert es länger.

View more Tutorials: