模組化的輸出與輸入

希望可以搞懂它。

三巨頭標準

  • Asynchronous Module Definition(AMD)

    非同步模組定義。可以想成是從 CommonJS 延伸出來的另一個標準,目的是提升瀏覽器在載入模組的效能。

  • CommonJS(CMJ)

    就是等下要介紹的東西,特別注意這種模組是用 同步 來載入模組的。

  • ES6(ESM)的 importexport

    之後出來的一個新標準,可以在 Node.js 跟瀏覽器上跑,詳細介紹可以參考 ES6 的模組機制

注意事項

這篇文章介紹的模組機制是「CommonJS」的標準,而採用這套標準的執行環境是「Node.js」,不是瀏覽器。也就是說 你沒辦法在瀏覽器上用這套標準。

如果你曾經看過有些瀏覽器上可以用,那也許是真的。不過正確一點的說法是「用了某些工具讓瀏覽器可以支援」才對,所以請不要誤會了。

輸出一個 module 給別人

假設我想寫一個 module 給別人用,那我可以這樣寫:

1
2
3
4
5
// myModule.js
function double(n) {
return n * 2
}
module.exports = double

module.exports 就是用來「把你想輸出的內容」給輸出。

在上面的例子裡我輸出了一個 function,但其實也可以改成 123'Hello' 或是 {name: 'PeaNu'} 等等,只要是符合 JavaScript 中的資料型態都可以。

載入寫好的 module

剛剛已經寫好 module 的部分了,接著我們要來載入:

1
2
3
// main.js
var myModule = require('./myModule')
console.log(myModule) // [Function: double]

require 就是用來「把你想輸入的內容」給輸入。

記得要指定一個變數來儲存引入的模組,接著這個變數就等同於剛剛寫好的模組。

所以把 myModule 印出來看就會得到剛剛寫好的 function: double

如果到這裡都沒問題的話,就可以使用模組了:

1
2
var myModule = require('./myModule')
console.log(myModule(100)) // 200

另外一種輸出方式

exports 是另外一種輸出方式,跟 module.exports 不同的地方是「只能以物件格式輸出」:

1
2
3
4
5
// myModule.js
function double(n) {
return n * 2
}
exports.double = double

所以引入的時候,只會拿到一個物件:

1
2
var myModule = require('./myModule')
console.log(myModule) // { double: [Function: double] }

簡單來說,你可以把 exports 想成是這樣:

1
2
3
4
5
{
double: function double(n) {
return n * 2
}
}

它不像 module.exports 那麼有彈性,想輸出什麼就輸出什麼,所以這個可能比較少用一點。

輸出多個內容

剛剛只有輸出一個 function,現在來多輸出幾個。

module.exports

1
2
3
4
5
6
7
8
9
10
function double(n) {
return n * 2
}
function triple(n) {
return n * 3
}
module.exports = {
double: double,
triple: triple
}
1
2
3
4
var myModule = require('./myModule')
console.log(myModule) // { double: [Function: double], triple: [Function: triple] }
console.log(myModule.double(2)) // 4
console.log(myModule.triple(2)) // 6

exports

1
2
3
4
5
6
7
8
function double(n) {
return n * 2
}
function triple(n) {
return n * 3
}
exports.double = double
exports.triple = triple
1
2
3
4
var myModule = require('./myModule')
console.log(myModule) // { double: [Function: double], triple: [Function: triple] }
console.log(myModule.double(2)) // 4
console.log(myModule.triple(2)) // 6

為什麼要有模組?

既然已經會使用了,那就要來談談為什麼要用它?

其實換個角度想就好了,如果沒有模組的話會怎麼樣?

舉個例子,假設我有兩個檔案,分別是 login.jsform.js。這兩個檔案都想用一個 function 來做「信箱驗證」的動作。在沒有模組的情況下只能這樣子做:

1
2
3
4
5
// login.js
function validEmail() {
...
}
validEmail(...)
1
2
3
4
5
// form.js
function validEmail() {
...
}
validEmail(...)

你應該能發現問題很明顯:

  1. 有幾個檔案要用,就要宣告幾個 validEmail
  2. 如果要修改 validEmail,那每一個檔案都得開起來一個一個改

但如果是模組化,就只會有兩個動作:

  1. 我要用 validEmail,就用一個變數來儲存 require 引入進來的東西
  2. 如果要修改 validEmail,我只要去這個模組的檔案修改就好

基於這兩點,其實就沒有不使用模組化的理由。

引用模組的注意事項 求出 1-100 的平方數
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×