借別人的東西來用:require
Module 模組
(Module 中國翻譯叫做“模塊”)
Module 就是「一個功能」
如果沒有 Module 的概念,那就會像這樣:把所有功能都放在一起
壞處是:每個功能之間依賴性太高,變得很難維護(改一個就動到另一個)
因此比較好的做法是「模組化」把功能切分開來:
- 有一個「登入功能」的 module
- 有一個「金流功能」的 module
- 有一個「會員功能」的 module
- 有一個「權限功能」的 module
最後用一個主程式,把每個 module 連接起來
模組化(module)在實務上的應用
在實務上,會把一些共同會用到的 function 抽出來放到一個叫做 utils.js 的檔案裡面,在其他各個地方要用到這些 function 時,再 import 進來
好處是:
因為 function 都只會放在 utils.js 這個檔案裡面
一個 function 的可重複使用性很高,且當我想要修改 function 時,就只要去 utils.js 裡面改就可以了
如何使用「別人提供的 module」
Node.js 有提供一些 module 可以使用:
像是其中一個叫做 OS
透過這些 module 可以拿到一些跟作業系統有關的資訊
module 使用方式如下:
- 宣告一個變數
os
(變數名稱可以自己取),用require
來引入 OS 這個 module - 這個
os
變數就代表「OS 這個 module」 - 小括號裡面填入「module 名稱」(用 string 的型態,因此要用單引號包起來)
var os = require('os')
現在,就可以開始使用 OS 模組了
例如:
使用其中一個 function 叫做 os.platform() 會回傳我的作業系統名稱
var os = require('os')
console.log(os.platform())
// output: darwin
darwin 是 Mac 核心的名稱
把東西借給別人:export
接下來要講的是:
自己要如何做出一個 module,然後讓別人或自己使用
作法如下:
- 新增一個檔案叫做 myModule.js,裡面就會放我要做的 module
- 假設在這個 module 裡面,我只提供了一個 function 讓人使用,也就是 double 函式
myModule.js:function double(n){ return n * 2 }
現在,我想要在另一個檔案 index.js 裡面,引入 myModule.js 這個 module 來使用,該怎麼做呢?
方法一 module.exports = double
- 在 myModule.js,用
module.exports = double
先把這個 module 「輸出」:
function double(n){
return n * 2
}
module.exports = double // 輸出 module
- 在 index.js 要引入 myModule.js 時,
在 require 小括號裡面,在「module 檔案名稱」前面要加上 ./
(也就是檔案路徑:./
代表是在同一個資料夾底下),因為這是我自己寫的 module,而不是系統(Node.js)提供的,所以要加上檔案路徑
var myModule = require('./myModule.js')
通常都會把副檔名省略不寫
module 檔案名稱的副檔名(.js)可以省略
var myModule = require('./myModule')
require 很聰明,如果沒寫副檔名的話,它就會自己去找有沒有 .js 的檔案
在 myModule.js「module.exports =
」後面接的東西,就會是 index.js「require」進來的東西
(在此範例中,就是指 double 函式)
因此,如果我在 index.js 把 myModule 印出來,結果就會是「double 函式」
var myModule = require('./myModule.js')
console.log(myModule)
// output: [Function: double]
因為現在的 myModule
變數就代表「double 函式」
因此,myModule(6)
就等於是 double(6)
var myModule = require('./myModule')
console.log(myModule(6))
// output: 12
變數名稱可以自己改
例如:我改成叫做 calc
var calc = require('./myModule')
console.log(calc(6))
// output: 12
可以 export 任何東西(數字、陣列、字串...都可以)
例如:我在 myModule.js export 一個陣列 [7, 8, 9]
function double(n){
return n * 2
}
module.exports = [7, 8, 9] // 輸出 module
那在 index.js 就會引入這個 [ 7, 8, 9 ]
陣列
var myModule = require('./myModule')
console.log(myModule)
// output: [ 7, 8, 9 ]
同時 export 很多個 function
通常,一個 module 裡面都會提供很多個 function,那要如何同時輸出這些 function 呢?
作法是:
export 一個物件 obj
,裡面放入所有我要輸出的 function
在物件 obj
裡面:
- key 是 double(可以自己隨意取名),value 是
double
(也就是 double 函式) - key 是 triple(可以自己隨意取名),value 是 triple 函式
function double(n){
return n * 2
}
var obj = {
double: double,
triple: function(n){
return n * 3
}
}
module.exports = obj
現在,我就可以在 index.js 裡面,使用 module 所有的 function 了
先把 module 印出來看看,結果當然也會是一個物件:
var myModule = require('./myModule')
console.log(myModule)
// output: { double: [Function: double], triple: [Function: triple] }
用物件的 key 來取用 function:
var myModule = require('./myModule')
console.log(myModule.double(4), myModule.triple(7))
// output: 8 21
為什麼可以這樣用?
背後運作的原理是:
因為這時的變數 myModule
就等同於是 obj
物件,像是這樣
var myModule = {
double: double,
triple: function (n) {
return n * 3
}
}
console.log(myModule.double(4), myModule.triple(7))
方法二 exports.double = double
在 myModule.js 除了使用 module.exports = double
來輸出之外,Node.js 提供了第二種寫法是 exports.double = double
myModule.js:
把 exports
本身當作一個空物件 {}
,輸出的東西就是一個物件
- 在
exports.
後面接的會是「物件的 key 名稱」(自己隨意取名) - 等號後面接 function 名稱
double
(就會是 hello 這個 key 的 value)
```javascript=
function double(n){
return n * 2
}
exports.hello = double
index.js:
把 myModule 印出來一樣會是一個物件
* key 是 hello
* value 是 double 函式
```javascript=
var myModule = require('./myModule')
console.log(myModule)
// output: { hello: [Function: double] }
輸出多個 function
也可以再 export 另一個函式
myModule.js:
function double(n){
return n * 2
}
exports.hello = double
exports.triple = function(n){
return n * 3
}
背後運作的原理:
把 exports
本身當作一個空物件 {}
所以在執行完 exports.hello = double
和 exports.triple = function(n){
return n * 3
}
之後,exports
物件就會像是這樣:
{
hello: double,
triple: function(n){
return n * 3
}
}
index.js:
把 myModule 印出來一樣會是一個物件,裡面有兩個 function
var myModule = require('./myModule')
console.log(myModule)
// output: { hello: [Function: double], triple: [Function] }
兩種方法的差別在於:
使用 module.exports = 789
的話,=
後面可以接任何東西(數字、字串、陣列、物件...都可以),也就是說:可以輸出任何東西(數字、字串、陣列、物件…都可以)
function double(n){
return n * 2
}
module.exports = 789
但如果是使用 exports.hello = double
的話,輸出的就一定會是一個「物件」
function double(n){
return n * 2
}
exports.hello = double
exports.triple = function(n){
return n * 3
}