JavaScript筆記(CommonJS規範)

參考網站:javascript

《模塊-廖雪峯的官方網站》
《CommonJS規範》
《js模塊化編程之完全弄懂CommonJS和AMD/CMD》css

爲了寫可維護的代碼,常把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對較少,不少編程語言都採用這種組織代碼的方式。
在Node環境中,一個.js文件就稱之爲一個模塊(module),每一個文件就是一個模塊,有本身的做用域,在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見,而Node應用由模塊組成,採用 CommonJS 模塊規範html

1 CommonJS規範

如下演示一個簡單的CommonJS規範實例:java

建立預引入文件 foo.jsnode

'use strict';

var x = 5;
function addx (value){
    console.log( x + value );
}
module.exports.addx = addx;

建立加載文件 main.js編程

'use strict'

var example = require('./foo.js');
example.addx(10);
//輸出:11 
module.exports.$ = example;

以上就是一個簡單的CommonJS規範實例,CommonJS規範規定,每一個模塊內部,module變量表明當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,實際上是加載該模塊的module.exports屬性(注意模塊的路徑描述)。json

CommonJS 模塊特色數組

  • 一、全部代碼都運行在模塊做用域,不會污染全局做用域
  • 二、模塊能夠屢次加載,可是隻會在第一次加載時運行一次,而後運行結果就被緩存了,之後再加載,就直接讀取緩存結果。要想讓模塊再次運行,必須清除緩存
  • 三、模塊加載的順序,按照其在代碼中出現的順序

瀏覽器不兼容CommonJS的根本緣由,正是在於缺乏四個Node.js環境的變量modulerequireexportsglobal瀏覽器

1.1 module對象

module對象,表明當前模塊。它有如下屬性:緩存

  • module.id 模塊的識別符,一般是帶有絕對路徑的模塊文件名
  • module.filename 模塊的文件名,帶有絕對路徑
  • module.loaded 返回一個布爾值,表示模塊是否已經完成加載
  • module.parent 返回一個對象,表示調用該模塊的模塊
  • module.children 返回一個數組,表示該模塊要用到的其餘模塊
  • module.exports 表示模塊對外輸出的值

如在main.js文件中,最後添加console.log(module)命令就能夠看出如下輸出結果:

Module {
  id: '.',//這裏是相對路徑
  exports: { '$': { addx: [Function: addx], x: 1 } },
  parent: null,
  filename: 'E:\\html&css\\test2.js',//這裏是絕對路徑
  loaded: false,
  children: 
   [ Module {
       id: 'E:\\html&css\\test.js',
       exports: [Object],
       parent: [Circular],
       filename: 'E:\\html&css\\test.js',
       loaded: true,
       children: [],
       paths: [Object] } ],
  paths: [ 'E:\\html&css\\node_modules', 'E:\\node_modules' ] }

1.2 module.exports屬性與exports變量

module.exports屬性表示當前模塊對外輸出的接口,其餘文件加載該模塊,實際上就是讀取module.exports
而爲了方便,Node爲每一個模塊提供一個exports變量,指向module.exports,正由於如此不能直接對exports變量賦值,由於這樣會等於切斷了exportsmodule.exports的聯繫

1.3 require方法

require方法其實不是一個全局命令,而是指向當前模塊的module.require命令。

1.3.1 加載規則

require命令用於加載文件,後綴名默認爲.js,但若是沒能查找,Node會嘗試爲文件名添加.js.json.node後,再去搜索。
若是參數字符串不以.//開頭,則表示加載的是一個默認提供的核心模塊(位於Node的系統安裝目錄中),或者一個位於各級node_modules目錄的已安裝模塊(全局安裝或局部安裝)。
舉例來講,腳本/home/user/projects/foo.js執行了require('bar.js')命令,Node會依次搜索如下文件:

  • /usr/local/lib/node/bar.js
  • /home/user/projects/node_modules/bar.js
  • /home/user/node_modules/bar.js
  • /home/node_modules/bar.js
  • /node_modules/bar.js

1.3.2 加載機制

CommonJS模塊的加載機制是,輸入的是被輸出的值的拷貝即一旦輸出一個值,模塊內部的變化就影響不到這個值,例如:

// foo.js
var counter = 3;
function incCounter() {
  counter++;
}
module.exports = {
  counter: counter,
  incCounter: incCounter,
};

// main.js
var counter = require('./lib').counter;
var incCounter = require('./lib').incCounter;
console.log(counter);  // 3
incCounter();
console.log(counter); // 3

1.3.3 模塊的緩存

第一次加載某個模塊時,Node會緩存該模塊。全部緩存的模塊保存在require.cache之中,若是想刪除模塊的緩存,能夠這樣寫:

// 刪除指定模塊的緩存
delete require.cache[moduleName];

// 刪除全部模塊的緩存
Object.keys(require.cache).forEach(function(key) {
  delete require.cache[key];
})
相關文章
相關標籤/搜索