Relación entre CommonJS, AMD y RequireJS?


Todavía estoy muy confundido acerca de CommonJS, AMD y RequireJS. Incluso después de leer mucho.

Sé que CommonJS (anteriormente ServerJS) es un grupo para definir algunas especificaciones de JavaScript (es decir, módulos) cuando el lenguaje se usa fuera del navegador. La especificación de módulos CommonJS tiene alguna implementación como Node.js o RingoJS, ¿verdad?

¿Cuál es la relación entre CommonJS, Asynchronous Module Definition (AMD) y RequireJS? Se requiere una implementación de CommonJS módulo definición? Si es así, ¿qué es AMD entonces?

Author: Greg K, 2013-05-13

5 answers

RequireJS implementa la API AMD (source).

CommonJS es una forma de definir módulos con la ayuda de un objeto exports, que define el contenido del módulo. En pocas palabras, una implementación de CommonJS podría funcionar así:

// 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"; };

Básicamente, CommonJS especifica que necesita tener una función require() para obtener dependencias, una variable exports para exportar el contenido del módulo y un identificador de módulo (que describe la ubicación del módulo en pregunta en relación con este módulo) que se utiliza para requerir las dependencias ( fuente ). CommonJS tiene varias implementaciones, incluyendo el nodo .js , que usted mencionó.

CommonJS no fue especialmente diseñado con los navegadores en mente, por lo que no encaja muy bien en el entorno del navegador (Realmente no tengo ninguna fuente para esto just solo lo dice en todas partes, incluyendo el sitio RequireJS.) Aparentemente, esto tiene algo que ver con la carga asíncrona, sucesivamente.

Por otro lado, RequireJS implementa AMD, que está diseñado para adaptarse al entorno del navegador ( source). Aparentemente, AMD comenzó como un spin-off del formato de transporte CommonJS y evolucionó en su propia API de definición de módulo. De ahí las similitudes entre los dos. La nueva característica de AMD es la función define() que permite al módulo declarar sus dependencias antes de cargarse. Por ejemplo, la definición podría ser:

define('module/id/string', ['module', 'dependency', 'array'], 
function(module, factory function) {
  return ModuleContents;  
});

Entonces, CommonJS y AMD son JavaScript API de definición de módulo que tienen diferentes implementaciones, pero ambas provienen del mismo origen.

  • AMD es más adecuado para el navegador, ya que admite la carga asíncrona de dependencias de módulos.
  • RequireJS es una implementación de AMD, mientras que al mismo tiempo intenta mantener el espíritu de CommonJS (principalmente en los identificadores de módulos).

Para confundirte aún más, Require Js, siendo un La implementación de AMD ofrece un contenedor CommonJS para que los módulos CommonJS se puedan importar casi directamente para su uso con RequireJS.

define(function(require, exports, module) {
  var someModule = require('someModule'); // in the vein of node    
  exports.doSomethingElse = function() { return someModule.doSomething() + "bar"; };
});

Espero que esto ayude a aclarar las cosas!

 695
Author: jakee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 15:43:17

CommonJS es más que eso: es un proyecto para definir una API y un ecosistema comunes para JavaScript. Una parte de CommonJS es la especificación Module. Nodo.js y RingoJS son tiempos de ejecución de JavaScript del lado del servidor, y sí, ambos implementan módulos basados en las especificaciones del módulo CommonJS.

AMD (Definición de Módulo asíncrono) es otra especificación para módulos. RequireJS es probablemente la implementación más popular de AMD. Una diferencia importante de CommonJS es que AMD especifica que los módulos se cargan asincrónicamente, lo que significa que los módulos se cargan en paralelo, en lugar de bloquear la ejecución esperando a que finalice una carga.

AMD generalmente se usa más en el desarrollo JavaScript del lado del cliente (en el navegador) debido a esto, y los módulos CommonJS generalmente se usan en el lado del servidor. Sin embargo, puede usar cualquier especificación de módulo en cualquier entorno - por ejemplo, RequireJS ofrece instrucciones para ejecutarse en Node.js y browserify es una implementación del módulo CommonJS que se puede ejecutar en el navegador.

 190
Author: Nate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-04 13:04:15

La respuesta corta sería:

CommonJS y AMD son especificaciones (o formatos) sobre cómo deben declararse los módulos y sus dependencias en las aplicaciones javascript.

RequireJS es una librería de script loader que es compatible con AMD, curljs siendo otro ejemplo.

Compatible con CommonJS:

Tomado de El libro de 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;

Compatible con AMD:

// 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
    }
});

En algún lugar de lo contrario, el módulo se puede utilizar con:

require(["package/myModule"], function(myModule) {
    myModule.foobar();
});

Algunos antecedentes:

En realidad, CommonJS es mucho más que una declaración API y solo una parte de ella se ocupa de eso. AMD comenzó como un borrador de especificación para el formato de módulo en la lista CommonJS, pero no se alcanzó un consenso completo y el desarrollo posterior del formato se trasladó al grupo amdjs . Argumentos en torno a qué formato es mejor estado que CommonJS intenta cubrir un conjunto más amplio de preocupaciones y que es más adecuado para el desarrollo del lado del servidor dada su naturaleza síncrona, y que AMD es más adecuado para el desarrollo del lado del cliente (navegador) dada su naturaleza asíncrona y el hecho de que tiene sus raíces en la implementación de la declaración de módulos de Dojo.

Fuentes:

 174
Author: mmutilva,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-04 00:55:51

Citando

AMD :

  • Un enfoque de navegador primero
  • Optando por el comportamiento asíncrono y la compatibilidad hacia atrás simplificada
  • No tiene ningún concepto de E/S de archivo.
  • Soporta objetos, funciones, constructores, cadenas, JSON y muchos otros tipos de módulos.

CommonJS :

  • Un primer acercamiento al servidor
  • Asumiendo comportamiento síncrono
  • Cubrir un conjunto más amplio de preocupaciones como E/S, Sistema de archivos, Promesas y más.
  • Soporta módulos sin envolver, puede sentirse un poco más cerca de los ES.next / Harmony especificaciones, liberándote de la envoltura define() que AMD impone.
  • Solo soporta objetos como módulos.
 21
Author: zangw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-07 01:02:35

Es bastante normal organizar el programa JavaScript modular en varios archivos y llamar a child-modules desde main js module.

La cosa es que JavaScript no proporciona esto. Ni siquiera hoy en día en las últimas versiones del navegador de Chrome y FF.

Pero, ¿hay alguna palabra clave en JavaScript para llamar a otro módulo JavaScript?

Esta pregunta puede ser un colapso total del mundo para muchos, porque la respuesta es No.


En ES5 (publicado en 2009 ) JavaScript no tenía palabras clave como import, include , or require.

ES6 salva el día (lanzado en 2015 ) proponiendo la palabra clave import ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import ), pero ningún navegador implementa esto.

Si utiliza Babel 6.18.0 y transpile solo con la opción ES2015

import myDefault from "my-module";

Obtendrá require de nuevo.

"use strict";
var _myModule = require("my-module");
var _myModule2 = _interopRequireDefault(_myModule);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

Esto se debe a que require significa que el módulo ser cargado desde el nodo.js. Nodo.js se encargará de todo, desde la lectura de archivos a nivel del sistema hasta las funciones de empaquetado en el módulo.

Porque en JavaScript las funciones son las únicas envolturas que representan los módulos.

Estoy muy confundido acerca de CommonJS y DMAE?

Tanto CommonJS como AMD son solo dos técnicas diferentes para superar el "defecto" de JavaScript para cargar módulos inteligentes.

 10
Author: prosti,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-08 16:12:25