參考網站:javascript
《模塊-廖雪峯的官方網站》
《CommonJS規範》
《js模塊化編程之完全弄懂CommonJS和AMD/CMD》css
爲了寫可維護的代碼,常把不少函數分組,分別放到不一樣的文件裏,這樣,每一個文件包含的代碼就相對較少,不少編程語言都採用這種組織代碼的方式。
在Node環境中,一個.js
文件就稱之爲一個模塊(module),每一個文件就是一個模塊,有本身的做用域,在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見,而Node應用由模塊組成,採用 CommonJS 模塊規範。html
如下演示一個簡單的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環境的變量:module
,require
,exports
,global
瀏覽器
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' ] }
module.exports
屬性與exports
變量module.exports
屬性表示當前模塊對外輸出的接口,其餘文件加載該模塊,實際上就是讀取module.exports
。
而爲了方便,Node爲每一個模塊提供一個exports
變量,指向module.exports
,正由於如此不能直接對exports
變量賦值,由於這樣會等於切斷了exports
與module.exports
的聯繫。
require
方法require
方法其實不是一個全局命令,而是指向當前模塊的module.require
命令。
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
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
第一次加載某個模塊時,Node會緩存該模塊。全部緩存的模塊保存在require.cache
之中,若是想刪除模塊的緩存,能夠這樣寫:
// 刪除指定模塊的緩存
delete require.cache[moduleName];
// 刪除全部模塊的緩存
Object.keys(require.cache).forEach(function(key) {
delete require.cache[key];
})