ホームページ  >  記事  >  ウェブフロントエンド  >  ノード(1)のモジュール仕様を0から1まで学習する

ノード(1)のモジュール仕様を0から1まで学習する

大家讲道理
大家讲道理オリジナル
2017-01-24 15:30:511137ブラウズ

CommonJS、AMD、CMD の概念を説明する前に、まず js のモジュール性について理解します。モジュール化とは、名前が示すように、プロジェクトを機能またはその他のロジックに従って分解し、各部分が 1 つの機能のみを処理し、将来の開発とメンテナンスを容易にするために機能を分離することです。次に、モジュール化には、モジュールを分割してアセンブルするための次の機能が必要です:

  1. カプセル化されたモジュールを定義する;

  2. 他のモジュールに依存することができる。 ;

  3. その後、これらの機能を定義するには一連の標準とガイドラインが必要になるため、CommonJS、AMD、CMD などが登場しました。

  4. 1. CommonJS

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的区别

可能有人见过直接使用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 );
        }
    }
})

这三个例子输出了三种结果:

  1. 声明a对象,并把a赋值给b,然后a和b输出了相同的结果;

  2. 改变了b中的name,那么a中的name也跟着改变;

  3. 重新声明了b对象,那么a中的name则没有跟着b一起改变

解释:a 是一个对象,b 是对 a 的引用,即 a 和 b 指向同一块内存,所以1中的输出是一样的。当对 b 作修改时,即 a 和 b 指向同一块内存地址的内容发生了改变,a 也会体现出来,所以第2个例子输出也一样。当 b 被覆盖时,b 指向了一块新的内存,a 还是指向原来的内存,所以最后输出会不一样。

那么此时就可以引出exportsmodule.exports了:

  1. module.exports 初始值为一个空对象 {}

  2. exports 是指向的 module.exports 的引用

  3. require() 返回的是 module.exports 而不是 exports

如果module.exports发生了新指向,则exports无效;若module.exports没有发生变化,则直接exports即可。

2. AMD与RequireJS

说到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定义,依赖通过函数参数传进来,这样的一个好处就是所有的依赖都能一目了然。

3. CMD与seajs

CMD规范是国内著名的玉伯大神提出来的,将就的就是就近依赖,什么时候用到,就在那个地方进行require

==============
rrreee🎜🎜同時に、必須ファイル内の任意の位置に記述できます。参照の前であれば、ファイルの先頭に記述する必要はありません。ただし、コードを読みやすくし、現在どのモジュールが参照されているかを直感的に確認するには、ファイルの先頭に配置するのが最善です。 🎜

exports と module.exports の違い

🎜 ここでは、exports を直接使用する場合と module.exports を使用する場合を見たことがあります。この 2 つの違いについて簡単に説明します。 🎜🎜まず簡単な例を見てみましょう: 🎜🎜rrreee🎜🎜 a と b の出力結果は同じです。ここで、b の name の値を変更します。 🎜🎜rrreee🎜🎜 a と b の両方の出力結果が変更されました。 b を再度宣言しました: 🎜🎜rrreee🎜🎜これら 3 つの例は 3 つの結果を出力します。 🎜🎜🎜🎜 オブジェクトを宣言し、 a を b に代入すると、 a と b は同じ結果を出力します 🎜🎜 🎜🎜 は b の名前を変更します。 a の名前も変更されます。🎜🎜🎜🎜 は b オブジェクトを再宣言しますが、a の名前は b とともに変更されません🎜🎜🎜🎜説明: a はオブジェクト、b はへの参照です。 a、つまり a と b は同じメモリを指すため、1 の出力は同じになります。 b が変更されると、つまり、同じメモリアドレスを指す a と b の内容が変更されると、a も反映されるため、2 番目の例の出力は同じになります。 b が上書きされると、b は新しいメモリを指しますが、a は引き続き元のメモリを指すため、最終的な出力は異なります。 🎜🎜次に、この時点で exportsmodule.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 のロジックに従って内部で実行されます。

4. 概要

この記事では、CommonJS、AMD、および CMD 仕様間の関連する相違点と関連性を紹介します。以下に簡単な概要を示します。

  1. CommonJS: 各ファイルはモジュールであり、定義する必要はありません。ノードはこの仕様を使用します。

  2. AMD: モジュールを定義するために定義を使用し、事前に依存関係に注意してください

  3. CMD: モジュールを定義するために定義を使用し、

    近くの依存関係を作成します

次に、ノードの正式な学習を開始します。


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。