首頁  >  文章  >  web前端  >  從0到1學習node(一)之模組規範

從0到1學習node(一)之模組規範

大家讲道理
大家讲道理原創
2017-01-24 15:30:511137瀏覽

在講解CommonJS, AMD, CMD這些概念之前,我們先兩個了解下js的模組化。模組化,顧名思義,就是將專案依照功能或其他邏輯分解處理,每個部分只處理一個功能,進行功能的解耦處理,方便以後的開發與維護。那麼模塊化必須具有以下的能力,才能進行模塊的拆分和組裝:

  1. 定義封裝的模塊;

  2. 定義新模塊對其他模塊的依賴;

  3. 可對其他模塊的引入支持;

那麼就需要一套規範準則來定義這些能力,於是就出現了CommonJS, AMD, CMD等。

1. CommonJS

CommonJS原先叫做ServerJS,是js在服務端的規範,node使用的就是這種規範。根據CommonJS規範,一個單獨的檔案就是一個模組,require用來載入一個模組,exports用來向外部暴露該模組裡的方法或屬性。

例如:

// hello.jsfunction say(username){    console.log( 'hello, '+username );
}

exports.say = say;

=============

// main.jsvar person = require('./hello');

person.say('wenzi'); // hello, wenziperson.say('师少兵'); // hello, 师少兵person.say('NUC'); // hello, NUC

同時,require語句可以寫在文件中的任何位置,只要使用先前引用之前即可,不一定要寫在文件的最前面。不過,為了程式碼更容易閱讀,能直觀地看到目前引用了哪些模組,最好是放在文件的最前面。

exports與module.exports的區別

可能有人見過直接使用exports的,有的是使用module.exports的,這裡稍微的講解下這兩者的區別。

先舉個簡單的例子:

var a = {name:'wenzi'};var b = a;console.log(a); // {name: "wenzi"}console.log(b); // {name: "wenzi"}

a和b輸出的結果是一樣的。現在我改變下b中name的值:

b.name = 'shaobing';console.log(a); // {name: "shaobing"}console.log(b); // {name: "shaobing"}

a和b的輸出結果都改變了。我再重新聲明b:

var b = {name:'师少兵'};console.log(a); // {name: "shaobing"}console.log(b); // {name: "师少兵"}

這三個例子輸出了三種結果:

  1. 聲明a對象,並把a賦值給b,然後a和b輸出了相同的結果;

  2. 改變了b中的name,那麼a中的name也跟著改變;
  3. 重新聲明了b對象,那麼a中的name也沒有跟著b一起改變
解釋

解釋

  1. 解釋

    :對象,b 是對a 的引用,即a 和b 指向同一塊內存,所以1中的輸出是一樣的。當 b 作修改時,即 a 和 b 指向同一塊記憶體位址的內容發生了改變,a 也會體現出來,所以第2個範例輸出也是一樣。當 b 被覆蓋時,b 指向了一塊新的內存,a 還是指向原來的內存,所以最後輸出會不一樣。

  2. 那麼此時就可以引出
  3. exports

    module.exports
  4. 了:
  5. module.exports 初始值為一個空對象{export

module.exports 初始值為一個空對象{export

require() 回傳的是module.exports 而不是exports

如果module.exports發生了新指向,則exports無效;若module.exports沒有發生變化,則直接exports即可。
2. AMD與RequireJS

說到AMD,不得不說到
RequireJS
,AMD從CommonJS社區獨立出來,單獨成為了AMD社區,AMD的流行,很大程度上也是依託了RequireJS作者的推廣。

AMD規範中,預設推薦的模組格式是:

// hello.js// 将需要引入的模块全部写入到数组中,然后传递参数进行调用define(['a', 'b'], function(a, ,b){    // do something    return{
        hello : function(username){            console.log( 'hello, '+username );
        }
    }
})

==========

<pre class="brush:js;toolbar:false;">// main.jsdefine([&amp;#39;./hello&amp;#39;], function(h){ h.hello(&amp;#39;wenzi&amp;#39;); })</pre>也就是說,在AMD中,模組必須使用define

定義,依賴透過函數參數傳進來,這樣的一個好處就是所有的依賴都能一目了然。
3. CMD與seajs🎜🎜CMD規範是國內著名的玉伯大神提出來的,將就的就是🎜就近依賴🎜,什麼時候用到,就在那個地方進行🎜require🎜。 SeaJS就是使用的CMD規格:🎜🎜
// hello.jsdefine(function(require, exports, module){    var a = require(&#39;a&#39;);    // do a    var b = require( &#39;b&#39; );    // do b    module.exports.hello = hello; // 对外输出hello})
🎜

從這裡也能看到AMD和CMD的區別:

AMD通常需要一次性引入全部的依賴,然後透過參數傳遞;而CMD則需要時才引入

不過,AMD也支持CMD這樣的引入格式,但內部還是依照AMD的邏輯執行。

4. 總結

這篇文章裡介紹了下CommonJS, AMD, CMD規範的相關區別與聯繫,這裡再簡要的總結下:

  1. CommonJS: 每個文件就是一個模組,沒有define定義,node使用此規範;

  2. AMD: 使用define定義一個模組,講究提前依賴

  3. CMD: 使用define定義模組,將就要開始正式進行node的學習了。


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn