Heim  >  Artikel  >  Web-Frontend  >  Detaillierte Erläuterung der Modulspezifikationen in JS (CommonJS, AMD, CMD)

Detaillierte Erläuterung der Modulspezifikationen in JS (CommonJS, AMD, CMD)

php是最好的语言
php是最好的语言Original
2018-08-07 09:21:442007Durchsuche

Antworten Sie mir zuerst: Warum sind Module wichtig?

Antwort: Dank der Module können wir den Code anderer Leute bequemer verwenden und beliebige Module für alle gewünschten Funktionen laden.
Hierfür gibt es allerdings eine Voraussetzung, das heißt, jeder muss das Modul gleich schreiben, sonst hat man seine Schreibweise, und ich habe meine Schreibweise, nicht es wird ein Durcheinander sein!

Daher wurden die folgenden drei Module standardisiert und dieser Artikel auch veröffentlicht (buchstabiert {Gesichtsbedeckung und Lachen}).

Modulspezifikation in JS (CommonJS, AMD, CMD), wenn Sie von js-Modularisierung gehört haben, dann sollten Sie davon gehört haben oder von CommonJS oder AMD oder sogar ich Ich habe von diesen CMD-Vorschriften gehört, aber bevor ich sie mir wirklich angehört habe. Schauen wir uns nun an, was diese Spezifikationen sind und was sie bewirken. Dieser Artikel enthält die Quellen dieser drei Spezifikationen und die Prinzipien der entsprechenden Produkte.

1. CommonJS

1. Zuerst dachten alle, JS sei eine heiße Frau , es ist nutzlos. Die offiziell definierte API kann nur browserbasierte Anwendungen erstellen, das ist zu eng (ein High-End-Wort wird verwendet, CommonJS-API kann es nicht mehr ertragen). Gemeinsame APIs, die von Anwendungen (hauptsächlich Nicht-Browser-Anwendungen) verwendet werden, schließen diese Lücke. Das ultimative Ziel besteht darin, eine Standardbibliothek bereitzustellen, die Python, Ruby und Java ähnelt. In diesem Fall können Entwickler die CommonJS-API zum Schreiben von Anwendungen verwenden, und diese Anwendungen können dann in verschiedenen JavaScript-Interpretern und verschiedenen Hostumgebungen ausgeführt werden.

In Systemen, die mit CommonJS kompatibel sind, können Sie JavaScript verwenden, um die folgenden Programme zu entwickeln:

(1) Serverseitige JavaScript-Anwendung

(2). Befehlszeilentool
(3). Titanium oder Adobe AIR)

Im Jahr 2009 erstellte der amerikanische Programmierer Ryan Dahl das Projekt node.js, um die Javascript-Sprache für die serverseitige Programmierung zu verwenden. Dies markiert die offizielle Geburtsstunde der „modularen Javascript-Programmierung“. Denn um ehrlich zu sein: In einer Browserumgebung ist das Fehlen von Modulen kein großes Problem. Schließlich ist die Komplexität von Webprogrammen begrenzt, aber auf der Serverseite müssen Module vorhanden sein, um mit dem Betriebssystem und anderen Anwendungen zu interagieren. sonst gibt es keine Möglichkeit. NodeJS ist eine Implementierung der CommonJS-Spezifikation, und Webpack ist ebenfalls in Form von CommonJS geschrieben.

Das Modulsystem von node.js wird unter Bezugnahme auf die CommonJS-Spezifikation implementiert. In CommonJS gibt es eine globale Methode require() zum Laden von Modulen. Vorausgesetzt, es gibt ein Mathematikmodul math.js, kann es wie folgt geladen werden.

var math = require('math');

Dann können Sie die von bereitgestellte Methode aufrufen Modul:

var math = require('math');

math.add(2,3); 5

Von CommonJS definierte Module sind unterteilt in: {Modulreferenz (erforderlich)} {Moduldefinition (Exporte)} {Modulidentifikation (Modul)}

require() wird zum Einführen externer Module verwendet. Das Exportobjekt wird zum Exportieren der Methoden oder Variablen des aktuellen Moduls verwendet. Der einzige Exportport repräsentiert das Modul selbst.

Obwohl Node den Spezifikationen von CommonJS folgt, wurden einige Kompromisse eingegangen und einige neue Dinge hinzugefügt.

Nachdem wir jedoch über CommonJS und auch über Node gesprochen haben, denke ich, dass wir zuerst NPM verstehen müssen. Als Paketmanager von Node soll NPM Node nicht bei der Lösung des Installationsproblems abhängiger Pakete unterstützen. Dann muss es auch der CommonJS-Spezifikation folgen. CommonJS WIKI spricht über seine Geschichte und stellt auch Module, Pakete usw. vor.

Lassen Sie uns über das Prinzip und die einfache Implementierung von commonJS sprechen:

Prinzip

Durchsuchen Der Hauptgrund, warum der Server nicht mit CommonJS kompatibel ist, ist das Fehlen von vier Node.js-Umgebungsvariablen.

  • Modul

  • Exporte

  • erforderlich

  • global

Solange diese vier Variablen bereitgestellt werden, kann der Browser das CommonJS-Modul laden.

Hier ist ein einfaches Beispiel.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">var module <span class="token operator">= <span class="token punctuation">{<br> exports<span class="token punctuation">: <span class="token punctuation">{<span class="token punctuation">}<br><span class="token punctuation">}<span class="token punctuation">;<br><br><span class="token punctuation">(<span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">) <span class="token punctuation">{<br> exports<span class="token punctuation">.multiply <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(n<span class="token punctuation">) <span class="token punctuation">{ <span class="token keyword">return n <span class="token operator">* <span class="token number">1000 <span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">(module<span class="token punctuation">, module<span class="token punctuation">.exports<span class="token punctuation">)<span class="token punctuation">)<br><br><span class="token keyword">var f <span class="token operator">= module<span class="token punctuation">.exports<span class="token punctuation">.multiply<span class="token punctuation">;<br><span class="token function">f<span class="token punctuation">(<span class="token number">5<span class="token punctuation">)<span class="token comment"> // 5000 <br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

Der obige Code stellt zwei externe Variablen, module und exports, für eine Funktion zur sofortigen Ausführung bereit. Das Modul wird innerhalb dieser Funktion platziert Ausführungsfunktion. Der Ausgabewert des Moduls wird in module.exports abgelegt, wodurch das Laden des Moduls realisiert wird.

2. Implementierung von Browserify

Wenn Sie das Prinzip kennen, können Sie es schaffen Werkzeuge . Browserify ist derzeit das am häufigsten verwendete Tool zur Konvertierung des CommonJS-Formats.

Sehen Sie sich ein Beispiel an, in dem das Modul main.js das Modul foo.js lädt.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><span class="token comment"><br>// foo.js<br>module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token comment"><br>// main.js<br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

Verwenden Sie den folgenden Befehl, um main.js in ein vom Browser verwendbares Format zu konvertieren.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browserify main<span class="token punctuation">.js <span class="token operator">> compiled<span class="token punctuation">.js<br/></span></span></span></code></span>

Was genau macht Browserify? Installieren Sie browser-unpack und Sie können klar sehen.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ npm install browser<span class="token operator">-unpack <span class="token operator">-g<br/></span></span></code></span>

Entpacken Sie dann die zuvor generierte Datei „compile.js“.

<span style="font-family:&#39;Microsoft YaHei&#39;;font-size:16px;"><code class="language-bash"><br/>$ browser<span class="token operator">-unpack <span class="token operator">< compiled<span class="token punctuation">.js<br/><br/><span class="token punctuation">[<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"module.exports = function(x) {\n console.log(x);\n};"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token punctuation">}<br/><span class="token punctuation">}<span class="token punctuation">,<br/><span class="token punctuation">{<br/><span class="token string">"id"<span class="token punctuation">:<span class="token number">2<span class="token punctuation">,<br/><span class="token string">"source"<span class="token punctuation">:<span class="token string">"var foo = require(\"./foo\");\nfoo(\"Hi\");"<span class="token punctuation">,<br/><span class="token string">"deps"<span class="token punctuation">:<span class="token punctuation">{<span class="token string">"./foo"<span class="token punctuation">:<span class="token number">1<span class="token punctuation">}<span class="token punctuation">,<br/><span class="token string">"entry"<span class="token punctuation">:<span class="token boolean">true<br/><span class="token punctuation">}<br/><span class="token punctuation">]<br/></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span>

Wie Sie sehen können, fügt browerify alle Module in ein Array ein, das id-Attribut ist die Nummer des Moduls und die Das Quellattribut ist der Quellcode des Moduls, das Deps-Attribut ist die Abhängigkeit des Moduls.

Da foo.js in main.js geladen wird, gibt das deps-Attribut ./foo entsprechend Modul Nr. 1 an. Wenn der Browser während der Ausführung auf die Anweisung require('./foo') stößt, führt er automatisch das Quellattribut von Modul Nr. 1 aus und gibt den ausgeführten Attributwert module.exports aus.

3. Tiny Browser erforderlich

Obwohl Browserify sehr leistungsfähig ist, kann es nicht im Browser bedient werden, was manchmal sehr umständlich ist.

Ich habe einen reinen Browser-CommonJS-Modullader tiny-browser-require basierend auf der internen Implementierung von Mocha erstellt. Es ist überhaupt keine Befehlszeile erforderlich. Geben Sie sie einfach direkt in den Browser ein. Der gesamte Code umfasst nur mehr als 30 Zeilen.

Die Logik ist sehr einfach: Das Modul wird in ein Array eingelesen, und der Ladepfad ist die ID des Moduls.

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br><span class="token keyword">function <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">var path <span class="token operator">= require<span class="token punctuation">.<span class="token function">resolve<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var mod <span class="token operator">= require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">]<span class="token punctuation">;<br><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">) <span class="token keyword">throw <span class="token keyword">new <span class="token class-name">Error<span class="token punctuation">(<span class="token string">'failed to require "' <span class="token operator">+ p <span class="token operator">+ <span class="token string">'"'<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">if <span class="token punctuation">(<span class="token operator">!mod<span class="token punctuation">.exports<span class="token punctuation">) <span class="token punctuation">{<br> mod<span class="token punctuation">.exports <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br> mod<span class="token punctuation">.<span class="token function">call<span class="token punctuation">(mod<span class="token punctuation">.exports<span class="token punctuation">, mod<span class="token punctuation">, mod<span class="token punctuation">.exports<span class="token punctuation">, require<span class="token punctuation">.<span class="token function">relative<span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<br><span class="token keyword">return mod<span class="token punctuation">.exports<span class="token punctuation">;<br><span class="token punctuation">}<br><br>require<span class="token punctuation">.modules <span class="token operator">= <span class="token punctuation">{<span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.resolve <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">var orig <span class="token operator">= path<span class="token punctuation">;<br><span class="token keyword">var reg <span class="token operator">= path <span class="token operator">+ <span class="token string">'.js'<span class="token punctuation">;<br><span class="token keyword">var index <span class="token operator">= path <span class="token operator">+ <span class="token string">'/index.js'<span class="token punctuation">;<br><span class="token keyword">return require<span class="token punctuation">.modules<span class="token punctuation">[reg<span class="token punctuation">] <span class="token operator">&& reg<br><span class="token operator">|| require<span class="token punctuation">.modules<span class="token punctuation">[index<span class="token punctuation">] <span class="token operator">&& index<br><span class="token operator">|| orig<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.register <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(path<span class="token punctuation">, fn<span class="token punctuation">)<span class="token punctuation">{<br> require<span class="token punctuation">.modules<span class="token punctuation">[path<span class="token punctuation">] <span class="token operator">= fn<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><br>require<span class="token punctuation">.relative <span class="token operator">= <span class="token keyword">function <span class="token punctuation">(parent<span class="token punctuation">) <span class="token punctuation">{<br><span class="token keyword">return <span class="token keyword">function<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">{<br><span class="token keyword">if <span class="token punctuation">(<span class="token string">'.' <span class="token operator">!<span class="token operator">= p<span class="token punctuation">.<span class="token function">charAt<span class="token punctuation">(<span class="token number">0<span class="token punctuation">)<span class="token punctuation">) <span class="token keyword">return <span class="token function">require<span class="token punctuation">(p<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var path <span class="token operator">= parent<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">'/'<span class="token punctuation">)<span class="token punctuation">;<br><span class="token keyword">var segs <span class="token operator">= p<span class="token punctuation">.<span class="token function">split<span class="token punctuation">(<span class="token string">'/'<span class="token punctuation">)<span class="token punctuation">;<br> path<span class="token punctuation">.<span class="token function">pop<span class="token punctuation">(<span class="token punctuation">)<span class="token punctuation">;<br><br><span class="token keyword">for <span class="token punctuation">(<span class="token keyword">var i <span class="token operator">= <span class="token number">0<span class="token punctuation">; i <span class="token operator">945e8d4292ce0af7e515c6c2ee692956<br><br>3f1c4e4b6b16bbbd69b2ee476dc4f83a<br>require.register("moduleId", function(module, exports, require){<br> // Module code goes here<br>});<br>var result = require("moduleId");<br>2cacc6d41bbb37262a98f745aa00fbf0<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

 还是以前面的 main.js 加载 foo.js 为例。

<code class="language-javascript"><span style="font-family:'Microsoft YaHei';font-size:16px;"><code class="language-javascript"><br>require<span class="token punctuation">.<span class="token function">register<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">, <span class="token keyword">function<span class="token punctuation">(module<span class="token punctuation">, exports<span class="token punctuation">, require<span class="token punctuation">)<span class="token punctuation">{<br> module<span class="token punctuation">.exports <span class="token operator">= <span class="token keyword">function<span class="token punctuation">(x<span class="token punctuation">) <span class="token punctuation">{<br> console<span class="token punctuation">.<span class="token function">log<span class="token punctuation">(x<span class="token punctuation">)<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">;<br><span class="token punctuation">}<span class="token punctuation">)<span class="token punctuation">;<br><br><span class="token keyword">var foo <span class="token operator">= <span class="token function">require<span class="token punctuation">(<span class="token string">"./foo.js"<span class="token punctuation">)<span class="token punctuation">;<br><span class="token function">foo<span class="token punctuation">(<span class="token string">"Hi"<span class="token punctuation">)<span class="token punctuation">;<br></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></span></code>

 注意,这个库只模拟了 require 、module 、exports 三个变量,如果模块还用到了 global 或者其他 Node 专有变量(比如 process),就通过立即执行函数提供即可。

二、AMD

基于commonJS规范的nodeJS出来以后,服务端的模块概念已经形成很自然地,大家就想要客户端模块。而且最好两者能够兼容,一个模块不用修改,在服务器和浏览器都可以运行。但是,由于一个重大的局限,使得CommonJS规范不适用于浏览器环境。还是上面的代码,如果在浏览器中运行,会有一个很大的问题,你能看出来吗?

  var math = require('math');

  math.add(2, 3);

 第二行math.add(2, 3),在第一行require('math')之后运行,因此必须等math.js加载完成。也就是说,如果加载时间很长,整个应用就会停在那里等。您会注意到 require 是同步的。

这对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于"假死"状态。

 因此,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。

CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的,AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。

AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。它采用异步方式加载模块,模块的加载不影响它后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成之后,这个回调函数才会运行。

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

  require([module], callback);

第一个参数[module],是一个数组,里面的成员就是要加载的模块;第二个参数callback,则是加载成功之后的回调函数。如果将前面的代码改写成AMD形式,就是下面这样:

  require(['math'], function (math) {

    math.add(2, 3);

  });

math.add() und das Laden des Mathematikmoduls sind nicht synchronisiert und der Browser friert nicht ein. Daher ist AMD offensichtlich besser für die Browserumgebung geeignet. Derzeit gibt es zwei Haupt-Javascript-Bibliotheken, die die AMD-Spezifikation implementieren: require.js und curl.js.

RequireJS implementiert die AMD-Spezifikation.

Detaillierte Zusammenfassung: Im Folgenden wird RequireJS als Beispiel zur Veranschaulichung der AMD-Spezifikation verwendet

1. Warum require .js verwenden?

In den Anfängen wurden alle Javascript-Codes in einer Datei geschrieben, und es reichte aus, diese eine Datei zu laden. Später gab es immer mehr Codes und eine Datei reichte nicht mehr aus. Sie musste in mehrere Dateien aufgeteilt und nacheinander geladen werden. Ich glaube, viele Leute haben den folgenden Webseitencode

 82aa3526d91a1e63399c31e3e88e82b62cacc6d41bbb37262a98f745aa00fbf0
 971749f558e9aa1fbc82591b103db9852cacc6d41bbb37262a98f745aa00fbf0
 847a2b365bb3326fcac7e8b83c77b8e107a3fefab51fd2d2ef02a4e62cbe2dba2cacc6d41bbb37262a98f745aa00fbf0
 a5b5ffe2660156a5fc46b07e767cb8819429d6e1efad07153846e528605c447e
 6b211ef2cac820d88c79506423962afa2cacc6d41bbb37262a98f745aa00fbf0

Dieser Code lädt mehrere JS-Dateien nacheinander.

Diese Schreibweise hat große Nachteile. Erstens stoppt der Browser beim Laden das Rendern der Webseite Wie im obigen Beispiel sollte 1.js vor 2.js stehen und das Modul mit der größten Abhängigkeit muss zuletzt geladen werden. Wenn die Abhängigkeiten komplex sind, wird das Schreiben und Warten von Code schwierig.

require.js wurde geboren, um diese beiden Probleme zu lösen:

 

 (1) Implementieren Sie das asynchrone Laden von JS-Dateien, um zu vermeiden, dass Webseiten die Reaktion verlieren.

 (2) Die Verwaltung zwischen Modulabhängigkeiten erleichtert das Schreiben von Code und Wartung.

2. Laden von require.js

Verwenden Sie require.js Der erste Schritt besteht darin, auf die offizielle Website zu gehen, um die neueste Version herunterzuladen.

Nach dem Herunterladen wird davon ausgegangen, dass Sie es im Unterverzeichnis js abgelegt haben und es geladen werden kann.

 7c439788e166f531c8ad0b30265c71032cacc6d41bbb37262a98f745aa00fbf0

Manche Leute denken vielleicht, dass das Laden dieser Datei auch dazu führen kann, dass die Webseite nicht mehr reagiert. Es gibt zwei Lösungen: Eine besteht darin, es unten auf der Webseite zu laden, die andere darin, es wie folgt zu schreiben:

 fedca1b25c3603a8614f7742da4635a02cacc6d41bbb37262a98f745aa00fbf0

Das async-Attribut gibt an, dass diese Datei asynchron geladen werden muss, um zu verhindern, dass die Webseite nicht mehr reagiert. Der IE unterstützt dieses Attribut nicht und unterstützt nur die Verzögerung, sodass auch die Verzögerung geschrieben wird.

Nach dem Laden von require.js besteht der nächste Schritt darin, unseren eigenen Code zu laden. Angenommen, unsere eigene Codedatei ist main.js und befindet sich ebenfalls im js-Verzeichnis. Dann schreiben Sie es einfach wie folgt:

 35be17e58c59207c30045b58673f385a< /script> ;

Das data-main-Attribut wird verwendet, um das Hauptmodul des Webprogramms anzugeben. Im obigen Beispiel befindet sich main.js im js-Verzeichnis. Diese Datei wird zuerst von require.js geladen. Da die Standarddateierweiterung von require.js js ist, kann main.js mit main abgekürzt werden.

3. So schreiben Sie das Hauptmodul

main.js aus dem vorherigen Ich nenne es das „Hauptmodul“, also den Zugangscode für die gesamte Webseite. Es ist ein bisschen wie die main()-Funktion in der C-Sprache, der gesamte Code beginnt hier zu laufen.

Werfen wir einen Blick darauf, wie man main.js schreibt.

Wenn unser Code nicht von anderen Modulen abhängt, können wir Javascript-Code direkt schreiben.

// main.js

warning("Laden erfolgreich!");

Aber in diesem Fall besteht keine Notwendigkeit, require.js zu verwenden. Eine wirklich häufige Situation besteht darin, dass das Hauptmodul von anderen Modulen abhängt. In diesem Fall muss die in der AMD-Spezifikation definierte Funktion require() verwendet werden.

// main.js

require(['moduleA', 'moduleB', ' moduleC'], function (moduleA, moduleB, moduleC){

    // etwas Code hier

 });

Die Funktion require() akzeptiert zwei Parameter. Der erste Parameter ist ein Array, das die Module angibt, von denen es abhängt. Das obige Beispiel ist ['moduleA', 'moduleB', 'moduleC'], das heißt, das Hauptmodul hängt von diesen drei Modulen ab Funktion Derzeit wird sie aufgerufen, nachdem alle oben angegebenen Module erfolgreich geladen wurden. Geladene Module werden als Parameter an diese Funktion übergeben, sodass diese Module innerhalb der Callback-Funktion verwendet werden können.

require() lädt ModulA, ModulB und ModulC asynchron, und die angegebene Rückruffunktion wird erst nach den vorherigen Modulen verwendet erfolgreich geladen werden, werden ausgeführt, wodurch das Abhängigkeitsproblem gelöst wird.

Schauen wir uns im Folgenden ein praktisches Beispiel an.

Angenommen, das Hauptmodul hängt von den drei Modulen jquery, underscore und backbone ab, kann main.js wie folgt geschrieben werden:

require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){

// etwas Code hier

 });

require.js lädt zuerst jQuery, Unterstrich und Backbone und führt dann die Rückruffunktion aus. Der Code des Hauptmoduls wird in die Callback-Funktion geschrieben.

4. Modulladen

Im letzten Beispiel des vorherigen Abschnitts wird das main Die abhängigen Module des Moduls sind ['jquery', 'underscore', 'backbone']. Standardmäßig geht require.js davon aus, dass sich diese drei Module im selben Verzeichnis wie main.js befinden und die Dateinamen jquery.js, underscore.js und backbone.js lauten, und lädt sie dann automatisch.

Mit der Methode require.config() können wir das Ladeverhalten des Moduls anpassen. require.config() wird an den Kopf des Hauptmoduls (main.js) geschrieben. Der Parameter ist ein Objekt und das paths-Attribut dieses Objekts gibt den Ladepfad jedes Moduls an.

require.config({

paths: {

"jquery" : "jquery.min",
"underscore": "underscore.min",
"backbone": "backbone.min"

 }

});

Der obige Code gibt drei Die Datei Name eines Moduls. Der Pfad ist standardmäßig das gleiche Verzeichnis wie main.js (js-Unterverzeichnis). Wenn sich diese Module in anderen Verzeichnissen befinden, beispielsweise im Verzeichnis js/lib, gibt es zwei Möglichkeiten, sie zu schreiben. Eine besteht darin, die Pfade einzeln anzugeben.

require.config({

Pfade: {

  "jquery": "lib/jquery.min",
  "underscore": "lib/underscore.min",
  "backbone": " lib/backbone.min"

  }

 });

Die andere Möglichkeit besteht darin, das Basisverzeichnis (baseUrl) direkt zu ändern.

require.config({

baseUrl: "js/lib",

Pfade: {

"jquery": "jquery.min",
"underscore": "underscore.min ",
 "backbone": "backbone.min"

  }

 });

Wenn sich ein Modul auf einem anderen Host befindet, können Sie dessen URL auch direkt angeben, z. B.:

require.config({

Pfade: {

 "jquery": "https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min"

 }

 });

require.js erfordert, dass jedes Modul eine separate js-Datei ist. In diesem Fall werden beim Laden mehrerer Module mehrere HTTP-Anfragen ausgegeben, was sich auf die Ladegeschwindigkeit der Webseite auswirkt. Daher bietet require.js ein Optimierungstool, mit dem Sie nach der Bereitstellung des Moduls mehrere Module in einer Datei zusammenführen können, um die Anzahl der HTTP-Anfragen zu reduzieren.

5. So schreiben Sie ein AMD-Modul

Das von require.js geladene Modul Verwendet werden AMD-Spezifikationen. Mit anderen Worten: Das Modul muss gemäß den AMD-Vorschriften geschrieben sein.

Konkret muss das Modul mit einer bestimmten define()-Funktion definiert werden. Wenn ein Modul nicht von anderen Modulen abhängig ist, kann es direkt in der Funktion define() definiert werden.

Angenommen, es gibt eine math.js-Datei, die ein Mathematikmodul definiert. Dann sollte math.js wie folgt geschrieben werden:

  // math.js

define(function (){

 var add = function (x,y){

   return x+y;

} ;

return {

add: add

 });

Die Lademethode ist wie folgt:

// js

require(['math'], function (math){

warning(math.add(1,1));

 });

Wenn dieses Modul auch von anderen Modulen abhängt, dann ist die Funktion define() der erste Parameter muss ein Array sein, das die Abhängigkeiten des Moduls angibt.

Define(['myLib'], function(myLib){

function foo(){

myLib.doSomething();

 }

return {

   foo : foo

  };

 }); 🎜>

Wenn die Funktion require() das obige Modul lädt, Die Datei myLib.js wird zuerst geladen.

6. Nicht standardmäßige Module laden

Theoretisch müssen die von require.js geladenen Module Module sein, die mit der Funktion define() gemäß AMD-Spezifikationen definiert wurden. Obwohl einige beliebte Funktionsbibliotheken (z. B. jQuery) bereits der AMD-Spezifikation entsprechen, ist dies bei vielen weiteren Bibliotheken nicht der Fall. Kann require.js also nicht standardmäßige Module laden?

Die Antwort ist ja.

Bevor Sie solche Module mit require() laden, müssen Sie zunächst die Methode require.config() verwenden, um einige ihrer Eigenschaften zu definieren.

Zum Beispiel sind die beiden Bibliotheken Underscore und Backbone nicht nach AMD-Spezifikationen geschrieben. Wenn Sie sie laden möchten, müssen Sie zunächst ihre Eigenschaften definieren.

require.config({

shim: {

'underscore' :{
exporte: '_'
},

deps: ['underscore', ' jquery'],
exportiert: 'Backbone'
}

  }

 });

require.config() akzeptiert ein Konfigurationsobjekt Zusätzlich zu dem zuvor erwähnten Pfadattribut außerdem ein Shim-Attribut, das speziell zur Konfiguration inkompatibler Module verwendet wird. Insbesondere muss jedes Modul (1) den Exportwert (Name der Ausgabevariable) definieren, der den Namen des Moduls angibt, wenn es extern aufgerufen wird; (2) das Deps-Array, das die Abhängigkeiten des Moduls angibt;

Ein jQuery-Plug-in kann beispielsweise so definiert werden:

Shim: {

 'jquery.scroll': {

  deps: ['jquery'],

Exporte: 'jQuery .fn.scroll'

  }

 }

7. require.js Plug-in

require.js bietet auch eine Reihe von Plug-ins zur Implementierung einiger spezifischer Funktionen.

domready Plug-in ermöglicht die Ausführung der Rückruffunktion, nachdem die Seiten-DOM-Struktur geladen wurde.

require(['domready!'], function (doc){

// wird aufgerufen, sobald das DOM bereit ist

 });

Text- und Bild-Plugins ermöglichen require.js das Laden von Text und Bildern dokumentieren.

 define([

    'text!review.txt',

    'image!cat.jpg'

    ],

    function(review,cat){

      console.log(review);

      document.body.appendChild(cat);

    }

  );

 类似的插件还有json和mdown,用于加载json文件和markdown文件。(完)

 另一个人的概括(有点简单):

AMD就只有一个接口:define(id?,dependencies?,factory);

 它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:

1 define([&#39;dep1&#39;,&#39;dep2&#39;],function(dep1,dep2){...});

 要是没什么依赖,就定义简单的模块,下面这样就可以啦:

<span style="font-family:&#39;幼圆&#39;;font-size:16px;">1 define(function(){<br/>2     var exports = {};<br/>3     exports.method = function(){...};<br/>4     return exports;<br/>5 });</span>

 咦,这里有define,把东西包装起来啦,那Node实现中怎么没看到有define关键字呢,它也要把东西包装起来呀,其实吧,只是Node隐式包装了而已.....

这有AMD的WIKI中文版,讲了很多蛮详细的东西,用到的时候可以查看:AMD的WIKI中文版

三、CMD

大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD蛮相近的,不过用起来感觉更加方便些,最重要的是中文版,应有尽有:seajs官方doc

1 define(function(require,exports,module){...});

用过seajs吧,这个不陌生吧,对吧。

前面说AMD,说RequireJS实现了AMD,CMD看起来与AMD好像呀,那RequireJS与SeaJS像不像呢?

虽然CMD与AMD蛮像的,但区别还是挺明显的,官方非官方都有阐述和理解,我觉得吧,说的都挺好:

官方阐述SeaJS与RequireJS异同

SeaJS与RequireJS的最大异同(这个说的也挺好)

相关推荐:

理解前端模块化(CommonJs,AMD和CMD)

JavaScript模块规范之AMD规范和CMD规范

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Modulspezifikationen in JS (CommonJS, AMD, CMD). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn