nodejs入門之CommonJS規範

CommonJS規範

1.概述

Node 應用由模塊組成,採用 CommonJS 模塊規範。

​ 每個文件就是一個模塊,有自己的作用域,在一個文件裏面定義的變量,函數,類,都是私有的,對其他文件不可見.

​ CommonJS規範規定,每個模塊內部,module變量代表當前模塊,這個變量是一個對象,它的exports屬性(module.exports)是對外的接口,加載某個模塊,其實就是加載該模塊的module.exports屬性

​ require方法用於加載模塊

​ CommonJS模塊特點如下:

​ 1.所有代碼都運行在模塊作用域,不會污染全局作用域

​ 2.模塊可以多次加載,但是隻會在第一次加載時運行一次,然後運行結果就被緩存了,以後 再加載,就直接讀取緩存結果,要想讓模塊再次運行,必須清除緩存

​ 3.模塊加載順序,按照其在代碼中出現的順序.

​ 4.模塊加載是同步的,也就是說只有加載完成,才能執行後面的操作

2.module對象

​ 每個模塊內部,都有一個module對象,代表當前模塊,它有以下屬性:

  • module.id 模塊的識別符,通常是帶有絕對路徑的模塊文件名

  • module.filename 模塊的文件名,帶有絕對路徑

  • module.loaded 返回一個布爾值,表示模塊是否已經完成加載

  • module.parent 返回一個對象,表示調用該模塊的模塊

  • module.children 返回一個數組,表示該模塊要用到的其他模塊

  • module.exports 表示對外輸出的值

    我們在當前一個js中直接輸出console.log(module);會輸出這樣一個module對象.

    { id: '.',
      exports: { '$': [Function] },
      parent: null,
      filename: '/path/to/index.js',
      loaded: false,
      children:
       [ { id: '/path/to/node_modules/jquery/dist/jquery.js',
           exports: [Function],
           parent: [Circular],
           filename: '/path/to/node_modules/jquery/dist/jquery.js',
           loaded: true,
           children: [],
           paths: [Object] } ],
      paths:
       [ '/home/user/deleted/node_modules',
         '/home/user/node_modules',
         '/home/node_modules',
         '/node_modules' ]
    }
    

module.exports

module.exports屬性表示當前模塊對外輸出的接口,其他文件加載該模塊,實際上是讀取module.exports

//idnex.js
var num=3;
function add(a,b){
    return a+b;
}

module.exports={
    add:add
}

//此處輸出跟上面效果一樣,這是es6,對象的簡寫,key,value一致,可以只寫一個
moudle.exports={
    add
}

//這種方式也是可以的
module.exports.add=add;//暴露方法
module.exports.num=num;//暴露變量

//在同目錄下的main.js 中
var example=require('./index');
example.add(1,2);  //3

exports變量

每個模塊化還提供一個exports變量,指向module.exports,這就等於在每個模塊頭部,都有一行隱藏的如下代碼

var exports=module.exports;

例如: exports.show=function(){console.log(123)}

注意:不能把exports直接指向一個值,這樣就相當於切斷了exports和module.exports的關係

例如:exports=10;

如果你覺得,exports與module.exports之間的區別很難分清,一個簡單的處理方法,就是放棄使用exports,只使用module.exports

3.AMD規範與CommonJS規範的兼容性

CommonJS規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操作。AMD規範則是非同步加載模塊,允許指定回調函數。由於Node.js主要用於服務器編程,模塊文件一般都已經存在於本地硬盤,所以加載起來比較快,不用考慮非同步加載的方式,所以CommonJS規範比較適用。但是,如果是瀏覽器環境,要從服務器端加載模塊,這時就必須採用非同步模式,因此瀏覽器端一般採用AMD規範。

4.require命令

1.基本用法

require命令的基本功能是,讀入並執行一個javascript文件,然後返回該模塊的module,exports對象,如果發現沒有指定模塊,會報錯.

2.加載規則

  • 後綴名默認爲.js
var show=require('show')
//等同於
var show=require('show.js')
//.js可以省略
  • 如果參數字符串以“/”開頭(linux)或者以 “D:/”盤符開頭(windows),則表示加載的是一個位於絕對路徑的模塊文件。比如,require(’/home/marco/foo.js’) 將加載 /home/marco/foo.js

  • 如果參數字符串以“./”開頭,則表示加載的是一個位於相對路徑(跟當前執行腳本的位置相比)的模塊文件。比如,require(’./circle’) 將加載當前腳本同一目錄的 circle.js

  • 如果參數字符串不以“./“或”/“開頭,則表示加載的是一個默認提供的核心模塊(位於Node的系統安裝目錄中),或者一個位於各級node_modules目錄的已安裝模塊(全局安裝或局部安裝)。

  • 如果參數字符串不以“./“或”/“開頭,而且是一個路徑,比如 require(‘example-module/path/to/file’),則將先找到 example-module 的位置,然後再以它爲參數,找到後續路徑。

  • 如果指定的模塊文件沒有發現,Node會嘗試爲文件名添加**.js、.json、.node**後,再去搜索。.js件會以文本格式的JavaScript腳本文件解析,.json文件會以JSON格式的文本文件解析,.node文件會以編譯後的二進制文件解析。

3.目錄的加載規則

通常,我們會把相關的文件會放在一個目錄裏面,便於組織。這時,最好爲該目錄設置一個入口文件,讓 require 方法可以通過這個入口文件,加載整個目錄。

在目錄中放置一個 package.json 文件,並且將入口文件寫入 main 字段。下面是一個例子。

// package.json
{ 
  "name" : "some-library",
  "main" : "./lib/some-library.js" 
}

require 發現參數字符串指向一個目錄以後,會自動查看該目錄的 package.json 文件,然後加載 main 字段指定的入口文件。如果 package.json 文件沒有 main 字段,或者根本就沒有 package.json 文件,則會加載該目錄下的index.js 文件 或者 index.json 文件 或者 index.node 文件。

4.模塊的加載機制

CommonJS模塊的加載機制是:輸出拷貝,也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值,上代碼瞭解一下:

//index.js
var num=1;
function add(){
    num++;
}

module.exports={
    num:num,
    add:add
}

現在呢,我們引入這個index.js

//main.js
var num=require("./index").num;
var add=require("./index").add;

console.log(num);//3
add();
console.log(num);//3

上述代碼說明,num輸出以後,index.js模塊內部的變化不會影響到咱們這邊調用時的num了

此文參考阮一峯大神文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章