web-dev-qa-db-ja.com

CommonJS、AMDとRequireJSの関係は?

私はまだCommonJS、AMD、RequireJSについて非常に混乱しています。たくさん読んでも。

CommonJS(以前のServerJS)は、言語がブラウザの外部で使用されるときにJavaScriptの仕様(つまりモジュール)を定義するためのグループであることを私は知っています。 CommonJSモジュールの仕様には、Node.jsやRingoJSなどの実装があります。

CommonJS、Asynchronous Module Definition(AMD)、RequireJSの関係は何ですか? RequireJSはCommonJSモジュール定義の実装ですか?もしそうなら、AMDは何ですか?

788
gremo

RequireJS _ amd _ API (source) を実装しています。

CommonJS は、モジュールの内容を定義するexportsオブジェクトを使用してモジュールを定義する方法です。簡単に言えば、CommonJSの実装は次のように動作します。

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

基本的に、CommonJSは、依存関係を取得するためのrequire()関数、モジュールの内容をエクスポートするためのexports変数、および依存関係を要求するために使用されるモジュール識別子(このモジュールに関連した問題のモジュールの位置を記述する)が必要です。 ( ソース ) CommonJSには、 Node.js など、さまざまな実装があります。

CommonJSはブラウザを念頭に置いて特別には設計されていなかったので、ブラウザ環境にはあまり適していません(このための情報源は本当にありません。 RequireJSサイトを含む)いたるところに言っています)どうやらこれは非同期ロードなどと関係があります。

一方、RequireJSはAMDを実装しています。これはブラウザ環境に合うように設計されています( ソース )。どうやら、AMDはCommonJS Transportフォーマットのスピンオフとして始まり、そして独自のモジュール定義APIへと進化しました。それ故に両者間の類似点。 AMDの新機能は、ロードされる前にモジュールがその依存関係を宣言することを可能にするdefine()関数です。たとえば、定義は次のようになります。

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

そのため、CommonJSとAMDは、実装が異なる JavaScript モジュール定義APIですが、どちらも同じ由来のものです。

  • _ amd _ は、モジュール依存関係の非同期ロードをサポートするため、ブラウザに適しています。
  • RequireJS _ amd _ の実装ですが、同時に CommonJS の精神を保とうとしています(主にモジュール識別子内)。

さらに混乱させるために、RequireJSはAMDの実装でありながらCommonJSラッパーを提供しているため、CommonJSモジュールをほぼ直接インポートしてRequireJSで使用することができます。

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

これが物事を明確にするのに役立つことを願っています!

733
jakee

CommonJS はそれ以上-JavaScriptの共通APIとエコシステムを定義するプロジェクトです。 CommonJSの一部は Module 仕様です。 Node.jsとRingoJSはサーバー側のJavaScriptランタイムであり、はい、どちらもCommonJS Module仕様に基づいたモジュールを実装しています。

AMD (非同期モジュール定義)は、モジュールのもう1つの仕様です。 RequireJS は、おそらくAMDの最も一般的な実装です。 CommonJSとの大きな違いの1つは、AMDがモジュールのロードasynchronouslyを指定していることです。つまり、モジュールは、終了する負荷。

通常、AMDはクライアント側(ブラウザー内)JavaScript開発でより多く使用され、CommonJSモジュールは通常サーバー側で使用されます。ただし、どちらの環境でもどちらのモジュール仕様も使用できます。たとえば、RequireJSは Node.jsで実行するための方向 および browserify を提供するCommonJS Module実装ですブラウザ。

194
Nate

簡単に言えば、

CommonJSおよび_ amd _は、JavaScriptアプリケーションでモジュールとその依存関係を宣言する方法に関する仕様(または形式)です。

RequireJSはAMDに準拠したスクリプトローダーライブラリです。 curljs は別の例です。

CommonJS準拠:

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;

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

他のどこかでこのモジュールを使用することができます。

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

いくつかの背景:

実のところ、 CommonJS はAPI宣言以上のものであり、その一部しか扱っていません。 AMDはCommonJSリストのモジュールフォーマットのドラフト仕様として始まりましたが、完全な合意には至らず、フォーマットのさらなる開発は amdjsグループ に移りました。どちらのフォーマットがより良いかについての議論は、CommonJSがより広範な一連の懸念をカバーしようとしており、その同期性を考えるとサーバサイド開発により適していると述べている。 Dojoのモジュール宣言の実装にルーツがあるという事実。

出典:

181
mmutilva

名言集

_ amd _

  • 1つのブラウザ優先アプローチ
  • 非同期動作と単純化された後方互換性の選択
  • ファイルI/Oの概念はありません。
  • オブジェクト、関数、コンストラクタ、文字列、JSON、その他多くの種類のモジュールをサポートしています。

CommonJS

  • 1つのサーバー優先アプローチ
  • 同期動作を想定する
  • I/O、ファイルシステム、プロミスなど、より幅広い一連の問題をカバーします。
  • ラップされていないモジュールをサポートし、 ES.next/Harmony 仕様にもう少し近づくことができ、AMDが強制するdefine()ラッパーから解放されます。
  • オブジェクトをモジュールとしてのみサポートします。
24
zangw

JavaScriptプログラムをモジュール化して複数のファイルにまとめ、child-modulesからmain js moduleを呼び出すのはごく普通のことです。

JavaScriptはこれを提供していません。 ChromeとFFの最新のブラウザバージョンでは今日でもそうではありません。

しかし、JavaScriptには他のJavaScriptモジュールを呼び出すためのキーワードがありますか。

答えは いいえ であるため、この質問は多くの人にとって世界の完全な崩壊かもしれません。


ES5(2009年リリース)では、JavaScriptに import include 、または require のようなキーワードはありませんでした。

ES6では、 import キーワード( https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/import )が提案されています(2015年にリリースされました)。これを実装しているブラウザはありません。

Babel 6.18.0を使用してES2015オプションのみで変換する場合

import myDefault from "my-module";

あなたは再びrequireを手に入れるでしょう。

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

これはrequireがモジュールがNode.jsからロードされることを意味するためです。 Node.jsはシステムレベルのファイルの読み込みからモジュールへの関数のラップまですべてを処理します。

JavaScriptでは、関数はモジュールを表す唯一のラッパーです。

私はCommonJSとAMDについて非常に混乱していますか?

CommonJSとAMDはどちらも、モジュールをスマートにロードするためのJavaScriptの「欠陥」を克服するための2つの異なる手法です。

12
prosti