从module的简单实现到模块化
前言
一直感覺模塊化是一個很神秘的概念,因而也很感興趣,有幸了解到了模塊化的歷史,嘗試著了解了一下模塊化的實現,發現了一個很有意思的東西,不知道為什么,會覺得很有成就感,記錄一下。
模塊化的實現
簡單模擬一下CMD的module實現,在module.js中做以下處理
//module.js exports.word = 'hello' module.exports = function () {console.log(exports.word) } 復制代碼然后在test.js界面引入該模塊
//test.js const file = require('./module.js') file() // hello console.log(file.word) //undefined 復制代碼不考慮為什么會有這樣的結果,上面的這部分是通過require引用模塊的常見寫法。下面的超簡化版本代碼實現了超簡化的require方法(下面的runner方法)
//require.js const fs = require('fs') const path = require('path')function runner(file) {const code = fs.readFileSync(path.join(__dirname, file), 'utf-8')const module = { exports: {} }const fn = new Function('module', 'exports', code)fn(module, module.exports)return module.exports } 復制代碼這里的fn整理出來就是下面這一段代碼
function _fn(module, exports) {exports.word = 'hello'module.exports = function() {console.log(exports.word)} } 復制代碼所以在執行fn(module, module.exports)時,就是對上面聲明的const module = { exports: {} }進行賦值。當執行runner方法時,其實就是獲取module.exports的值。而runner方法做的事,就是獲取文件中的內容,識別module.exports,并把該值拋出來。轉到require,其實主要做的也就是這部分工作。module和 export也就成了關鍵詞,用來在讀取模塊的時候識別的標識。
runner方法已經實現了,現在來看一下為什么運行后是這樣的結果。
export 與 module.export
通過上面runner的實現,也可以看出,其實exports和module.exports最后被引用后其實是一個。最后暴露出來的都是module對象,而如果一個頁面中同時存在exports和module.exports,最后一個引用都會覆蓋掉掉前面所有的exports引用,所以這也是為什么上面的file()能執行成功,而file.word為undefined,因為前者覆蓋了后者。file已經被替換成了下面這個方法
function() {console.log(exports.word) } 復制代碼模塊化
那么什么叫模塊化呢?我的理解有3點:
因為看了模塊化的歷史,了解到模塊化最最原始是從匿名閉包衍生出來的,再看看現在的module的實現,其實也是一個閉包。雖然之前看了很多閉包的概念,但因為使用上的局限性,一直把閉包誤解為只有return出去的才是閉包。比如下面這段代碼
function fo(){var a = 'aaa';return function(){console.log(a)} } var bar = fo(); 復制代碼這次看到這個是真的有刷新我的認知,原來下面這樣的也是閉包
var b = {a: {} } function fo(obj){let a = 'aaa';obj.a = function(){console.log(a)} } fo(b.a); 復制代碼把上面這個再擴展一下就成了下面這段代碼,一段類似_fn的代碼
var b = {a: {} } function fo(b, a){a = '111';b.a = function(){console.log(a)} } fo(b, b.a); 復制代碼重復一波閉包的概念:能夠讀取其他函數內部變量的函數。
所以這也是為什么上面的file()的結果是hello,這也是requireJS的模塊化里面我暫時接觸到的最有意思的地方。下次瞅一瞅es6的模塊化
相關知識
模塊化的歷史:huangxuan.me/js-module-7…
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的从module的简单实现到模块化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: redis 原码安装
- 下一篇: ElasticSearch6.5.0 【