JavaScript 標準參考教程(alpha)javascript
CommonJS規範(推薦 - 阮一峯寫的)html
官方網站 (看半天,不知道幹啥!)java
CommonJS 是什麼 ? (有些暈)node
這裏基本環境安裝配置就不說了,本身查找資料。jquery
使用webstrom ,使用 node 記得enable ,寫相關命令的時候,纔會提醒顯示:
如圖:個人是已經打開的webpack
不管是node
應用模塊,仍是webpack
配置 ,均是採用CommonJS
模塊化規範。git
Example :github
example.jsweb
/** * Created by yuan on 2/21/2017. */ var x = 1; var addX = function (value) { return value + x; } module.exports.x = x; #對外提供值 module.exports.addX = addX; #對外提供函數
example-test.jsnpm
/** * Created by yuan on 2/21/2017. */ var example = require('./example.js') #加載模塊 console.log(example.x) #調用value console.log(example.addX(12)); #調用函數
執行 : node xxx.js 執行 js 文件
D:\webworkspace\webpack-demo\commond>node example1-test.js 1 13
規範:
js
文件就是一個模塊,有本身的做用域 ;js
文件定義的函數,變量,類都是私有的;全部的模塊都是一個module對象,表明當前模塊
Example :
引入jquery , 打印當前module ;
D:\webworkspace\webpack-demo\commond>npm install jquery -g C:\Users\yuan\AppData\Roaming\npm `-- jquery@3.1.1
"dependencies": { "jquery": "^3.1.1", }
/** * Created by yuan on 2/21/2017. */ var jquery= require('jquery'); exports.$ = jquery; console.log(module);
D:\webworkspace\webpack-demo\commond>node example2.js Module { id: '.', #模塊識別,一般是模塊的絕對路徑文件名 exports: { '$': [Function] },#模塊對外輸出的接口 parent: null, # 返回對象,表示調用該模塊的模塊 filename: 'D:\\webworkspace\\webpack-demo\\commond\\example2.js', # 絕對路徑的模塊名 loaded: false, # 表示是否加載完成 children: # 表示該模塊依賴的其餘模塊 [ Module { id: 'D:\\webworkspace\\webpack-demo\\node_modules\\jquery\\dist\\jquery.js', exports: [Function], parent: [Circular], filename: 'D:\\webworkspace\\webpack-demo\\node_modules\\jquery\\dist\\jquery.js', loaded: true, children: [], paths: [Object] } ], paths: [ 'D:\\webworkspace\\webpack-demo\\commond\\node_modules', 'D:\\webworkspace\\webpack-demo\\node_modules', 'D:\\webworkspace\\node_modules', 'D:\\node_modules' ] }
(1)認識module
module.exports 當前模塊對外輸出的接口,對外提供變量;在每一個模塊中默認實現了
var exports=module.exports;
Example 1 :
/** * 返回x平方與y平方和 * @param x * @param y * @returns {number} */ function add(x, y) { return x * x + y * y; } // exports.add = add; // 對外提供add函數 // module.exports.add = add; //對外提供add函數
結果:
上面兩種寫法,實現的效果是同樣的;建議使用 module.exports 來作,我以爲代碼清晰。
Example 2 :
//ok exports.hello = function () { console.log('hello node!') }; //error1 : 該exports 賦值 就和 module.exports 沒有了聯繫! exports = function (x) { console.log(x); }; //error2 : module.exports = 'hello commonJS';
結果:
注意: 不能夠對exports 或 module.exports 直接賦值,否則exports 就和 module 自己的exports 沒有關係了。
require
加載模塊文件: 讀入並執行javascript
文件 ,返回該module.exports
對象
Example :
example.js
var sayHi = function (name) { console.log(name + ' say hi !'); console.log(require.main===module); #false }; module.exports.sayhi = sayHi;
example-test.js
var say = require('./example.js'); #加載上面的exmple.js console.log(say.sayhi('labelnet')); console.log(require.main === module); #true
執行
D:\webworkspace\webpack-demo\commond>node example4-test.js labelnet say hi ! false undefined true
總結:
require.main === module
能夠判斷模塊是直接執行的仍是被調用執行的,若是直接執行返回true , 被調用的返回false;
進行加載時,默認後綴名時 .js , 也就是說 require('./example4.js')
和 require('./example4')
效果實現同樣的。
參數格式:
參數格式決定了不一樣路徑尋找模塊文件
require('/yuan/dist/example.js')
require('./example4') require('./example4.js')
require('jquery')
每一個模塊被加載時,只執行一次,其他的都去緩存中獲取;
requrie.cache
Example :
require('./example'); require('./example').message = 'hello js'; console.log(require('./example').message);
上面代碼,加載了三次example, 第二次添加message 變量,第三次打印message變量;
結果:
D:\webworkspace\webpack-demo\commond>node example5-test.js hello js
說明 第三次的結果是從緩存中獲取的;
刪除緩存
刪除緩存,必須知道緩存模塊的絕對路徑,才能夠刪除;
基本格式 :
delete require.cache[模塊絕對路徑];
Example :
require('./example'); require('./example').message = 'hello js'; // console.log(module); //能夠獲取到模塊的絕對路徑 delete require.cache['D:\\webworkspace\\webpack-demo\\commond\\example.js']; //刪除指定模塊緩存,緩存是根據絕對路徑識別的!! console.log(require('./example').message);
結果:
D:\webworkspace\webpack-demo\commond>node example5-test.js undefined
刪除所有緩存
Object.keys(require.cache).forEach(function (key) { delete require.cache[key]; });
對外輸出的值,是這個值得拷貝(複製),若是這個值內部值改變,那麼對外輸出的值並不改變;
Example :
先打印外部值,改變內部值,再次打印外部值;
example.js
var value = 3; function add() { value++; console.log('內部 value +1 : ' + value) } module.exports = { value: value, add: add, };
example-test.js
/** * Created by yuan on 2/21/2017. */ var test= require('./exapmle6'); console.log('外部 value 執行1 : '+test.value); console.log(test.add()); console.log('外部 value 執行2 : '+test.value);
結果:
D:\webworkspace\webpack-demo\commond>node example6-test.js
外部 value 執行1 : 3 內部 value +1 : 4 undefined 外部 value 執行2 : 3
require
不是一個全局命令,而是指向當前模塊的module.require
命令,然後者又調用Node
的內部命令Module._load
。
Module._load = function(request, parent, isMain) { // 1. 檢查 Module._cache,是否緩存之中有指定模塊 // 2. 若是緩存之中沒有,就建立一個新的Module實例 // 3. 將它保存到緩存 // 4. 使用 module.load() 加載指定的模塊文件, // 讀取文件內容以後,使用 module.compile() 執行文件代碼 // 5. 若是加載/解析過程報錯,就從緩存刪除該模塊 // 6. 返回該模塊的 module.exports };
上面的第4步,採用 module.compile()
執行指定模塊的腳本,邏輯以下。
Module.prototype._compile = function(content, filename) { // 1. 生成一個require函數,指向module.require // 2. 加載其餘輔助方法到require // 3. 將文件內容放到一個函數之中,該函數可調用 require // 4. 執行該函數 };
上面的第1步和第2步,require函數及其輔助方法主要以下。
一旦require函數準備完畢,整個所要加載的腳本內容,就被放到一個新的函數之中,這樣能夠避免污染全局環境。該函數的參數包括require、module、exports,以及其餘一些參數。
(function (exports, require, module, __filename, __dirname) { // YOUR CODE INJECTED HERE! });
Module._compile
方法是同步執行的,因此Module._load
要等它執行完成,纔會向用戶返回module.exports
的值 。
轉自:https://blog.csdn.net/LABLENET/article/details/56287947