首先:Tree Shaking只支持ES模塊的使用犁苏,不支持require這種動(dòng)態(tài)引入模塊的方式硬萍。
CommonJS | ESModule |
---|---|
輸出的是值的淺拷貝 | 輸出的是值的引用 |
動(dòng)態(tài)引入、運(yùn)行時(shí)加載 | 靜態(tài)引入围详、編譯時(shí)執(zhí)行 |
require() 是同步加載模塊 | import是異步加載模塊朴乖,靜態(tài)編譯時(shí)加載,有獨(dú)立的模塊依賴解析 |
exports和module.export區(qū)別:
- exports:對(duì)于本身來(lái)講是一個(gè)變量(對(duì)象)助赞,它不是module的引用买羞,它是{}的引用,它指向module.exports的{}模塊雹食。默認(rèn)指向 module.exports 的內(nèi)存空間畜普,只能使用.語(yǔ)法 向外暴露變量。
- module.exports:module是一個(gè)變量群叶,指向一塊內(nèi)存吃挑,exports是module中的一個(gè)屬性,存儲(chǔ)在內(nèi)存中街立,然后exports屬性指向{}模塊舶衬。既可以使用.語(yǔ)法,也可以使用=直接賦值赎离。
require() 返回的是 module.exports 而不是 exports
CommonJS用同步的方式加載模塊逛犹。在服務(wù)端,模塊文件都存放在本地磁盤,讀取非乘浠快舞蔽,所以這樣做不會(huì)有問(wèn)題。但是在瀏覽器端码撰,限于網(wǎng)絡(luò)原因渗柿,更合理的方案是使用異步加載。
ES6的模塊不是對(duì)象脖岛,import命令會(huì)被 JavaScript 引擎靜態(tài)分析做祝,在編譯時(shí)就引入模塊代碼,而不是在代碼運(yùn)行時(shí)加載鸡岗,所以無(wú)法實(shí)現(xiàn)條件加載混槐。也正因?yàn)檫@個(gè),使得靜態(tài)分析成為可能轩性。
CommonJS 模塊輸出的是一個(gè)值的拷貝声登,ES6 模塊輸出的是值的引用
- CommonJS 模塊輸出的是值的拷貝,也就是說(shuō)揣苏,一旦輸出一個(gè)值悯嗓,模塊內(nèi)部的變化就影響不到這個(gè)值。
- ES6 模塊的運(yùn)行機(jī)制與 CommonJS 不一樣卸察。JS 引擎對(duì)腳本靜態(tài)分析的時(shí)候脯厨,遇到模塊加載命令import,就會(huì)生成一個(gè)只讀引用坑质。等到腳本真正執(zhí)行時(shí)合武,再根據(jù)這個(gè)只讀引用,到被加載的那個(gè)模塊里面去取值涡扼。換句話說(shuō)稼跳,ES6 的import有點(diǎn)像 Unix 系統(tǒng)的“符號(hào)連接”,原始值變了吃沪,import加載的值也會(huì)跟著變汤善。因此,ES6 模塊是動(dòng)態(tài)引用票彪,并且不會(huì)緩存值红淡,模塊里面的變量綁定其所在的模塊。
CommonJS 模塊是運(yùn)行時(shí)加載降铸,ES6 模塊是編譯時(shí)輸出接口
CommonJS 加載的是一個(gè)對(duì)象(即module.exports屬性)在旱,該對(duì)象只有在腳本運(yùn)行完才會(huì)生成。而 ES6 模塊不是對(duì)象垮耳,它的對(duì)外接口只是一種靜態(tài)定義颈渊,在代碼靜態(tài)解析階段就會(huì)生成。
- 運(yùn)行時(shí)加載: CommonJS 模塊就是對(duì)象终佛;即在輸入時(shí)是先加載整個(gè)模塊俊嗽,生成一個(gè)對(duì)象,淺拷貝緩存到內(nèi)存中铃彰,然后再?gòu)倪@個(gè)對(duì)象上面讀取方法绍豁,這種加載稱為“運(yùn)行時(shí)加載”。下次加載文件時(shí)牙捉,直接從內(nèi)存中取值竹揍。
- 編譯時(shí)加載: ES6 模塊不是對(duì)象,而是通過(guò) export 命令顯式指定輸出的代碼邪铲,import時(shí)采用靜態(tài)命令的形式芬位。即在import時(shí)可以指定加載某個(gè)輸出值,而不是加載整個(gè)模塊带到,這種加載稱為“編譯時(shí)加載”昧碉。模塊內(nèi)部引用的變化,會(huì)反應(yīng)在外部揽惹。
- ES Module 是編譯時(shí)執(zhí)行被饿,而 CommonJS 模塊是在運(yùn)行時(shí)加載;
ES Module 最大的特點(diǎn)就是靜態(tài)化,在編譯時(shí)就能確定模塊的依賴關(guān)系搪搏,以及輸入和輸出的值狭握,這意味著模塊的依賴關(guān)系是確定的,和運(yùn)行時(shí)的狀態(tài)無(wú)關(guān)疯溺,可以進(jìn)行可靠的靜態(tài)分析论颅,正是基于這個(gè)基礎(chǔ),才使得 Tree-Shaking 成為可能!