CommonJS、AMD、CMD の概念を説明する前に、まず js のモジュール性について理解します。モジュール化とは、名前が示すように、プロジェクトを機能またはその他のロジックに従って分解し、各部分が 1 つの機能のみを処理し、将来の開発とメンテナンスを容易にするために機能を分離することです。次に、モジュール化には、モジュールを分割してアセンブルするための次の機能が必要です:
カプセル化されたモジュールを定義する;
他のモジュールに依存することができる。 ;
その後、これらの機能を定義するには一連の標準とガイドラインが必要になるため、CommonJS、AMD、CMD などが登場しました。
CommonJS は元々は ServerJS
と呼ばれるもので、サーバー側の js の仕様です。 CommonJS 仕様によれば、単一のファイルがモジュールであり、require
はモジュールのロードに使用され、exports
は使用されます。 > は、このモジュール内のメソッドまたはプロパティを外部に公開するために使用されます。
// hello.jsfunction say(username){ console.log( 'hello, '+username ); } exports.say = say;
ServerJS
,是js在服务端的规范,node使用的就是这种规范。根据CommonJS规范,一个单独的文件就是一个模块,require
用来加载一个模块,exports
用来向外部暴露该模块里的方法或属性。例如:
// main.jsvar person = require('./hello'); person.say('wenzi'); // hello, wenziperson.say('师少兵'); // hello, 师少兵person.say('NUC'); // hello, NUC
=============
var a = {name:'wenzi'};var b = a;console.log(a); // {name: "wenzi"}console.log(b); // {name: "wenzi"}
同时,require
语句可以写在文件中的任何位置,只要使用之前引用之前即可,不一定要写在文件的最前面。不过,为了代码更易阅读,能直观地看到当前引用了哪些模块,最好是放在文件的最前面。
可能有人见过直接使用exports的,有的是使用module.exports的,这里稍微的讲解下这两者的区别。
先举个简单的例子:
b.name = 'shaobing';console.log(a); // {name: "shaobing"}console.log(b); // {name: "shaobing"}
a和b输出的结果是一样的。现在我改变下b中name的值:
var b = {name:'师少兵'};console.log(a); // {name: "shaobing"}console.log(b); // {name: "师少兵"}
a和b的输出结果都发生了改变。我再对b进行重新声明:
// hello.js// 将需要引入的模块全部写入到数组中,然后传递参数进行调用define(['a', 'b'], function(a, ,b){ // do something return{ hello : function(username){ console.log( 'hello, '+username ); } } })
这三个例子输出了三种结果:
声明a对象,并把a赋值给b,然后a和b输出了相同的结果;
改变了b中的name,那么a中的name也跟着改变;
重新声明了b对象,那么a中的name则没有跟着b一起改变
解释:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以1中的输出是一样的。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,a 也会体现出来,所以第2个例子输出也一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后输出会不一样。
那么此时就可以引出exports
和module.exports
了:
module.exports 初始值为一个空对象 {}
exports 是指向的 module.exports 的引用
require() 返回的是 module.exports 而不是 exports
如果module.exports发生了新指向,则exports无效;若module.exports没有发生变化,则直接exports即可。
说到AMD,不得不说到RequireJS
,AMD从CommonJS社区独立出来,单独成为了AMD社区,AMD的流行,很大程度上也是依托了RequireJS作者的推广。
AMD规范中,默认推荐的模块格式是:
// main.jsdefine(['./hello'], function(h){ h.hello('wenzi'); })
==========
// hello.jsdefine(function(require, exports, module){ var a = require('a'); // do a var b = require( 'b' ); // do b module.exports.hello = hello; // 对外输出hello})
也就是说,在AMD中,模块必须使用define
定义,依赖通过函数参数传进来,这样的一个好处就是所有的依赖都能一目了然。
CMD规范是国内著名的玉伯大神提出来的,将就的就是就近依赖
,什么时候用到,就在那个地方进行require
必須
ファイル内の任意の位置に記述できます。参照の前であれば、ファイルの先頭に記述する必要はありません。ただし、コードを読みやすくし、現在どのモジュールが参照されているかを直感的に確認するには、ファイルの先頭に配置するのが最善です。 🎜exports
と module.exports
を導入できます: 🎜🎜🎜🎜module.exports初期値は空のオブジェクトです。{}🎜🎜🎜🎜exports は module.exports への参照です🎜🎜🎜🎜require() は、exports の代わりに module.exports を返します🎜🎜🎜🎜 module.exports に新しいポイントがある場合、エクスポートは無効です。module.exports が変更されていない場合は、直接エクスポートしてください。 🎜🎜2. AMD と RequireJS🎜🎜 AMD と言えば、RequireJS
の人気について話さなければなりません。 AMD、それはまた、RequireJS 作者の昇進にも大きく依存しています。 🎜🎜 AMD 仕様では、デフォルトで推奨されるモジュール形式は次のとおりです: 🎜🎜rrreee🎜🎜==========🎜🎜rrreee🎜🎜 つまり、AMD では、モジュールは define
定義では、依存関係は関数パラメーターを通じて渡されます。これの利点の 1 つは、すべての依存関係が一目でわかることです。 🎜🎜3. CMD と seajs🎜🎜 CMD 仕様は、中国の有名な Yu Bo によって提案されました。それが使用される場合、唯一の解決策は 近くの依存関係
です。その場所は必須
です。 SeaJS は CMD 仕様を使用します: 🎜🎜rrreee🎜ここから AMD と CMD の違いを確認することもできます:
AMD は通常、すべての依存関係を一度に導入し、パラメータを通じて渡す必要がありますが、CMD は必要な場合にのみ導入します
ただし、AMD は導入もサポートしています。 CMD 形式ですが、依然として AMD のロジックに従って内部で実行されます。
この記事では、CommonJS、AMD、および CMD 仕様間の関連する相違点と関連性を紹介します。以下に簡単な概要を示します。
CommonJS: 各ファイルはモジュールであり、定義する必要はありません。ノードはこの仕様を使用します。
AMD: モジュールを定義するために定義を使用し、事前に依存関係に注意してください
近くの依存関係を作成します