實作模組機制

有東西搞不清楚?實作一遍就清楚了。

前情提要

(注意:閱讀這篇文章前請先弄懂 理解 function 傳遞參數的機制 的內容,不然你會看得霧煞煞。)

這裡要實作的是可以在瀏覽器上運行的 module.exportsrequire

簡單回顧一下用途,這裡有兩個檔案分別為 main.jsutils.js

main.js 負責引入 utils.js 中寫好的模組,如下:

1
2
3
4
5
6
7
8
9
// utils.js
function calculate(n) {
return ((n * 100 + 20 - 4)) % 10 + 3
}

module.exports = {
cal: calculate,
name: 'hello'
}
1
2
3
4
// main.js
var obj = require('./utils')
console.log(obj.cal(30)) // 9
console.log(obj.name) // hello

因為 obj 實際上儲存的值等同於 module.exports 等號後面的物件,所以你也可以這樣理解:

1
2
3
4
5
6
7
// 可以想成是這樣子
var obj = module.exports
// 示意碼
var obj = {
cal: calculate,
name: 'hello'
}

所以換句話說,只要實作 require('./utils') 能夠回傳 module.exports 這個物件就大功告成了。

開始動工

首先把 main.js 的內容用一個 function 包起來,然後傳入一個 require(一個 function):

1
2
3
4
5
6
7
// handmade.js
function main(require) {
// 此處的 require 是一個 function
var obj = require('./utils')
console.log(obj.cal(30))
console.log(obj.name)
}

接著把 utils.js 的內容也用一個 function 包起來,然後傳入一個 module(一個 object):

1
2
3
4
5
6
7
8
9
10
11
12
// handmade.js
function utilis(module) {
function calculate(n) {
return ((n * 100 + 20 - 4)) % 10 + 3
}

// 此處的 module 是一個 object
module.exports = {
cal: calculate,
name: 'hello'
}
}

要特別注意一點,utilis() 會把傳進來的參數 module 給新增一個 exports 屬性。

也就是說只要傳一個 object 進去,這個 object 就會被新增一個 exports 屬性來儲存模組的內容。

(再次提醒,如果你不懂這裡的運作原理,請回去複習 理解 function 傳遞參數的機制

馬上來試試看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// handmade.js
function utilis(module) {
function calculate(n) {
return ((n * 100 + 20 - 4)) % 10 + 3
}
module.exports = {
cal: calculate,
name: 'hello'
}
}

// 用來傳入 utilis 的空物件
var m = {}
// 執行後 m 會被新增一個 exports 屬性儲存內容
utilis(m)
// { cal: [Function: calculate], name: 'hello' }
console.log(m.exports)

做到這裡我們就已經完成建立 module.exports 的部分了,接著只要再讓 require(./utils) 能夠回傳 module.exports 的內容就完成了:

1
2
3
4
5
6
7
8
9
10
11
12
// handmade.js
function main(require) {
var obj = require('./utils')
console.log(obj.cal(30))
console.log(obj.name)
}

var r = function(m) {
// 回傳 m.exports 中的內容(物件)
return m.exports
}
main(r)

附上完整的程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function utilis(module) {
function calculate(n) {
return ((n * 100 + 20 - 4)) % 10 + 3
}
module.exports = {
cal: calculate,
name: 'hello'
}
}
function main(require) {
// './utils' 只是示意用,與實作內容無關
var obj = require('./utils')
console.log(obj.cal(30)) // 9
console.log(obj.name) // hello
}


var m = {}
utilis(m) // 輸出模組


var r = function() {
return m.exports
}
main(r) // 引入模組

直接複製這一段程式碼去跑,不管在 Node.js 或瀏覽器都可以正常運行。

參考資料

webpack 新手教學之淺談模組化與 snowpack

清除雜訊的重要性 mentor-program-day13
Your browser is out-of-date!

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

×