Je suis encore très confus à propos de CommonJS, AMD et RequireJS. Même après avoir lu beaucoup.
Je sais que CommonJS (anciennement ServerJS) est un groupe permettant de définir certaines spécifications JavaScript (par exemple, des modules) lorsque la langue est utilisée en dehors du navigateur. La spécification des modules CommonJS a une implémentation telle que Node.js ou RingoJS, non?
Quelle est la relation entre CommonJS, AMD (Asynchronous Module Definition) et RequireJS? RequireJS est-il une implémentation de la définition de module CommonJS? Si oui, qu'est-ce que la DMLA alors?
RequireJS implémente l'API AMD(source) .
CommonJS est un moyen de définir des modules à l'aide d'un objet exports
, qui définit le contenu du module. En termes simples, une implémentation CommonJS pourrait fonctionner comme ceci:
// someModule.js
exports.doSomething = function() { return "foo"; };
//otherModule.js
var someModule = require('someModule'); // in the vein of node
exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
En gros, CommonJS spécifie que vous devez avoir une fonction require()
pour récupérer les dépendances, une variable exports
pour exporter le contenu du module et un identifiant de module (qui décrit l'emplacement du module en question par rapport à ce module). ) qui est utilisé pour requérir les dépendances ( source ). CommonJS a diverses implémentations, y compris Node.js , que vous avez mentionné.
CommonJS n’a pas été conçu spécialement pour les navigateurs, il n’est donc pas adapté à l’environnement de navigateur (. Je n’ai vraiment aucune source pour cela - cela est dit partout, y compris le site RequireJS.) Apparemment, cela a quelque chose à voir avec le chargement asynchrone, etc.
D'autre part, RequireJS implémente AMD, conçu pour s'adapter à l'environnement du navigateur ( source ). Apparemment, AMD a commencé comme une retombée du format de transport CommonJS et a évolué vers sa propre API de définition de module. D'où les similitudes entre les deux. La nouvelle fonctionnalité d'AMD est la fonction define()
qui permet au module de déclarer ses dépendances avant d'être chargé. Par exemple, la définition pourrait être:
define('module/id/string', ['module', 'dependency', 'array'],
function(module, factory function) {
return ModuleContents;
});
Ainsi, CommonJS et AMD sont des API de définition de module JavaScript JavaScript qui ont des implémentations différentes, mais les deux proviennent des mêmes origines.
Pour vous dérouter encore plus, RequireJS, tout en étant une implémentation AMD, offre un wrapper CommonJS afin que les modules CommonJS puissent être presque directement importés pour une utilisation avec RequireJS.
define(function(require, exports, module) {
var someModule = require('someModule'); // in the vein of node
exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
});
J'espère que cela aide à clarifier les choses!
CommonJS est plus que cela - c'est un projet pour définir une API et un écosystème communs pour JavaScript. Une partie de CommonJS est la spécification Module . Node.js et RingoJS sont des exécutions JavaScript côté serveur. Oui, les deux implémentent des modules basés sur les spécifications du module CommonJS.
AMD (Définition du module asynchrone) est une autre spécification pour les modules. RequireJS est probablement l'implémentation la plus répandue d'AMD. Une différence majeure par rapport à CommonJS est que AMD spécifie que les modules sont chargés de manière asynchrone - ce qui signifie que les modules sont chargés en parallèle, par opposition à bloquer l'exécution en attendant une charge à finir.
AMD est généralement plus utilisé dans le développement JavaScript côté client (dans le navigateur) et les modules CommonJS sont généralement utilisés côté serveur. Toutefois, vous pouvez utiliser l'une ou l'autre des spécifications de module dans l'un ou l'autre environnement - par exemple, RequireJS offre instructions pour l'exécution dans Node.js et browserify est une implémentation du module CommonJS pouvant s'exécuter dans le processus. navigateur.
CommonJS et AMD sont des spécifications (ou formats) sur la façon dont les modules et leurs dépendances doivent être déclarés dans des applications javascript.
RequireJS est une bibliothèque de chargeur de script compatible AMD, curljs étant un autre exemple.
Tiré de livre d'Addy Osmani .
// package/lib is a dependency we require
var lib = require( "package/lib" );
// behavior for our module
function foo(){
lib.log( "hello world!" );
}
// export (expose) foo to other modules as foobar
exports.foobar = foo;
// package/lib is a dependency we require
define(["package/lib"], function (lib) {
// behavior for our module
function foo() {
lib.log( "hello world!" );
}
// export (expose) foo to other modules as foobar
return {
foobar: foo
}
});
Ailleurs, le module peut être utilisé avec:
require(["package/myModule"], function(myModule) {
myModule.foobar();
});
En fait, CommonJS est beaucoup plus qu'une déclaration d'API et seule une partie de celle-ci traite de cela. AMD a commencé comme une spécification préliminaire pour le format de module de la liste CommonJS, mais aucun consensus n'a été atteint et le développement du format a été déplacé vers le groupe groupe amdjs . Les arguments autour desquels le format est le mieux indiqué indiquent que CommonJS tente de couvrir un plus grand nombre de problèmes, qu’il convient mieux au développement côté serveur en raison de sa nature synchrone et que AMD convient mieux au développement côté client (navigateur), en raison de sa nature asynchrone et de la fait qu'il a ses racines dans l'implémentation de la déclaration de module de Dojo.
AMD:
CommonJS :
AMD
applique.Il est tout à fait normal d’organiser le programme JavaScript de manière modulaire en plusieurs fichiers et d’appeler child-modules
à partir du main js module
.
La chose est que JavaScript ne fournit pas cela. Pas même aujourd'hui dans les dernières versions de navigateur de Chrome et FF.
Mais y a-t-il un mot-clé en JavaScript pour appeler un autre module JavaScript?
Cette question peut être un effondrement total du monde pour beaucoup parce que la réponse est Non .
Dans ES5 (sorti en 2009), JavaScript ne comportait aucun mot clé comme import , include , ou nécessite .
ES6 enregistre la date (publiée en 2015) en proposant le mot clé import ( https://developer.mozilla.org/en/docs/ Web/JavaScript/Référence/Instructions/import ), mais aucun navigateur ne l'implémente.
Si vous utilisez Babel 6.18.0 et transpilez uniquement avec l’option ES2015
import myDefault from "my-module";
vous obtiendrez require
à nouveau.
"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
En effet, require
signifie que le module sera chargé à partir de Node.js. Node.js gérera tout, de la lecture de fichier au niveau système aux fonctions d'encapsulation dans le module.
Parce que dans JavaScript, les fonctions sont les seuls wrappers pour représenter les modules.
CommonJS et AMD sont-ils confus?
CommonJS et AMD ne sont que deux techniques différentes permettant de surmonter le "défaut" de JavaScript pour charger des modules intelligemment.