es6 javascript module requirejs amd commonjs

javascript - es6 - ¿Relación entre CommonJS, AMD y RequireJS?



commonjs vs es6 (5)

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 idioma se usa fuera del navegador. La especificación de los módulos CommonJS tiene alguna implementación como Node.js o RingoJS, ¿verdad?

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


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 biblioteca de cargadores de scripts que cumple con AMD, siendo curljs otro ejemplo.

Compatible con CommonJS:

Tomado del 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;

Cumple 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 otro lugar 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 de API y solo una parte trata con eso. AMD comenzó como un borrador de especificación para el formato del módulo en la lista de CommonJS, pero no se alcanzó un consenso total y el desarrollo posterior del formato se trasladó al AMD . Los argumentos sobre qué formato es mejor indican que CommonJS intenta cubrir un conjunto más amplio de inquietudes y que es más adecuado para el desarrollo del lado del servidor debido a su naturaleza sincrónica, y que AMD es más adecuado para el desarrollo del lado del cliente (navegador) debido a su naturaleza asíncrona y hecho que tiene sus raíces en la implementación de la declaración del módulo de Dojo.

Fuentes:


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

La cosa es que JavaScript no proporciona esto. Ni siquiera hoy en día en las últimas versiones de 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 (lanzado en 2009), JavaScript no tenía palabras clave como importar , incluir o requerir .

ES6 salva el día (publicado en 2015) al proponer la palabra clave de importación ( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import ), pero ningún navegador lo implementa.

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

import myDefault from "my-module";

obtendrá require 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 se cargará desde Node.js. Node.js manejará todo, desde la lectura de archivos a nivel del sistema hasta las funciones de ajuste 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 AMD?

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


Quoting

AMD :

  • Un primer enfoque del navegador
  • Optando por un comportamiento asíncrono y compatibilidad hacia atrás simplificada.
  • No tiene ningún concepto de E / S de archivos.
  • Es compatible con objetos, funciones, constructores, cadenas, JSON y muchos otros tipos de módulos.

CommonJS :

  • Un enfoque de servidor primero
  • Suponiendo un comportamiento sincrónico
  • Cubra un conjunto más amplio de inquietudes, como E / S, sistema de archivos, promesas y más.
  • Admite módulos sin envolver, puede sentirse un poco más cerca de las especificaciones de ES.next/Harmony , liberándole del envoltorio define () que AMD aplica.
  • Solo admite objetos como módulos.

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 del Module . Node.js y RingoJS son tiempos de ejecución de JavaScript del lado del servidor, y sí, ambos implementan módulos basados ​​en la especificación 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 con respecto a CommonJS es que AMD especifica que los módulos se cargan de forma asíncrona , lo que significa que los módulos se cargan en paralelo, en lugar de bloquear la ejecución al esperar a que finalice una carga.

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


RequireJS implementa la API de AMD (source) .

CommonJS es una forma de definir módulos con la ayuda de un objeto de 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 de exportación para exportar el contenido del módulo y un identificador de módulo (que describe la ubicación del módulo en cuestión en relación con este módulo) que se usa para requerir Las dependencias ( source ). CommonJS tiene varias implementaciones, incluyendo Node.js , que mencionaste.

CommonJS no fue diseñado especialmente teniendo en cuenta los navegadores, por lo que no encaja muy bien en el entorno del navegador ( realmente no tengo ninguna fuente para esto, solo lo dice en todas partes, incluido el sitio RequireJS ) . Aparentemente, esto tiene algo que ver con hacer con carga asíncrona, etc.

Por otro lado, RequireJS implementa AMD, que está diseñado para adaptarse al entorno del navegador ( source ). Aparentemente, AMD comenzó como una escisión del formato de transporte de CommonJS y evolucionó a su propio 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 ser cargado. Por ejemplo, la definición podría ser:

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

Por lo tanto, CommonJS y AMD son API de definición de módulos de JavaScript que tienen diferentes implementaciones, pero ambas provienen de los mismos orígenes.

  • 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 confundirlo aún más, RequireJS, aunque es una 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!