- Node.js+Webpack開發(fā)實(shí)戰(zhàn)
- 夏磊
- 1086字
- 2021-03-26 21:53:48
3.4 Node.js的模塊系統(tǒng)
Node.js應(yīng)用由模塊組成,采用CommonJS模塊規(guī)范。
每個JS文件就是一個模塊,有獨(dú)立的作用域。在一個文件中定義的變量、函數(shù)、類在其他文件都不可見。
// example.js function sum(a, b) { return a + b; }
上述代碼中sum函數(shù)只有example.js中能調(diào)用,其他文件則不可以調(diào)用。
3.4.1 module和exports
1.基本用法
CommonJS規(guī)范規(guī)定,每個模塊內(nèi)部的變量module代表當(dāng)前模塊。
module是一個對象,module.exports是對外的接口。加載模塊實(shí)際上是讀取該模塊的module.exports屬性。
module.exports也是一個對象,所有需要導(dǎo)出的變量、函數(shù)、類都需要掛載到該對象上才能實(shí)現(xiàn)導(dǎo)出。
// example.js function sum(a, b) { return a + b; } module.exports.sum = sum;
為了方便起見,Node.js為每個模塊提供了一個exports變量,在同一個模塊中,module.exports和exports是恒等的(類型和值都相等)。因此在實(shí)際開發(fā)中,建議通過exports.xxx的形式導(dǎo)出變量、函數(shù)、類。
不建議更改exports的指向,否則模塊將不能正常導(dǎo)出。
下列代碼無法導(dǎo)出sum函數(shù),因為exports由于重新賦值導(dǎo)致指向被更改。
// example.js exports.sum = function(a, b) { return a + b; } exports = 'Hello World';
如果模塊只需要導(dǎo)出一個變量、函數(shù)、類,只能對module.exports進(jìn)行賦值,對exports進(jìn)行賦值達(dá)不到如期作用。
上面講到module.exports是恒等于exports的,為什么對exports進(jìn)行賦值達(dá)不到如期作用呢?
// a.js exports = 'hello world'; // b.js module.exports = 'hello world'; // c.js const hello = require('./a'); console.log(hello); // {} const hello2 = require('./b'); console.log(hello2); // hello world
2.原理解讀
exports只是一個別名,類似于下面的代碼:
var exports = module.exports;
當(dāng)不對exports重新賦值時,exports指向不變,exports.xxx也會如期地添加到module.exports中。
當(dāng)對exports重新賦值時,exports和module.exports關(guān)聯(lián)就不存在了,修改exports不會對module.exports產(chǎn)生作用。
3.4.2 require
1.基本用法
CommonJS規(guī)定require用于加載模塊文件。
require讀取并執(zhí)行一個JS模塊,然后返回該模塊的exports對象。如果模塊未找到,則會拋出錯誤。
// math.js exports.sum = function(a, b) { return a + b; } // index.js const math = require('./math'); math.sum(1, 1);
2.加載規(guī)則
加載模塊時模塊擴(kuò)展名為.js。也就是說下列代碼是一樣的:
const math = require('./math'); const math2 = require('./math2');
根據(jù)傳入的參數(shù),require會有不同的規(guī)則(以下規(guī)則無先后順序):
(1)如果參數(shù)以'/'開頭,則表示需要加載的是一個絕對路徑的JS文件。如require('/home/xialei/math')將加載/home/xialei/math.js。
(2)如果參數(shù)字符串是以'./'開頭,則表示需要加載一個相對路徑的模塊文件。如require('./math')將加載位于當(dāng)前模塊同目錄下的math.js文件。
(3)如果參數(shù)不以'./'或'/'開頭,則需要加載的是核心模塊或者當(dāng)前工作目錄中node_modules下的模塊。
(4)如果沒有找到指定的模塊文件,Node.js會嘗試自動添加.js、.json、.node(編譯后的二進(jìn)制模塊)后再去搜索。
(5)如果傳入的參數(shù)解析之后是一個目錄,Node.js會自動讀取該目錄下的package.json文件,根據(jù)main字段來加載真正的入口文件。如果該目錄下沒有package.json文件,則嘗試加載index.js或index.node。
3.4.3 開發(fā)一個自定義模塊
我們將開發(fā)一個與時間操作相關(guān)的函數(shù)模塊來鞏固本節(jié)所學(xué),示例代碼如下。
date.js:

index.js:
const date = require('./date'); const now = parseInt(Date.now() / 1000, 10); console.log(date.formatTime(now - 60)); console.log(date.formatTime(now - 600)); console.log(date.formatTime(now - 5400)); console.log(date.formatTime(now - 3600 * 23)); console.log(date.formatTime(now - 3600 * 24)); console.log(date.formatTime(now - 3600 * 24 * 3)); 在終端輸入以下命令執(zhí)行index.js: node index.js
輸出如下:
剛剛 1小時內(nèi) 3小時內(nèi) 今天 1天前 Fri Oct 23 2019 18:07:45 GMT+0800 (中國標(biāo)準(zhǔn)時間)
- HTML5+CSS3+JavaScript從入門到精通:上冊(微課精編版·第2版)
- 自己動手寫搜索引擎
- JavaScript全程指南
- 機(jī)器學(xué)習(xí)系統(tǒng):設(shè)計和實(shí)現(xiàn)
- 小創(chuàng)客玩轉(zhuǎn)圖形化編程
- Learning AndEngine
- Kinect for Windows SDK Programming Guide
- PHP+MySQL網(wǎng)站開發(fā)項目式教程
- Mastering ServiceNow(Second Edition)
- PySpark Cookbook
- Machine Learning With Go
- 動手打造深度學(xué)習(xí)框架
- 零基礎(chǔ)學(xué)HTML+CSS
- App Inventor少兒趣味編程動手做
- 青少年學(xué)Python(第2冊)