最近在看vue源碼,而後看到了rollup,而後又看到了模塊化的概念,因此對模塊化的概念進行一個學習和總結。如下就是個人學習成果,若是有什麼不對的歡迎指教。javascript
模塊化存在的意義:開發者但願在開發過程當中只須要關注本身的核心業務邏輯,其餘的能夠直接加載別人寫好的模塊。可是Javascript不是一種模塊化編程語言,在es6之前,它是不支持」類」(class),因此也就沒有」模塊」(module)了(借鑑而來)vue
nodejs一個應用於服務器端編程被提出時,Javascript模塊化也所以誕生,CommonJS模塊規範被提出。在es6模塊以前,CommonJS統一了模塊化編程。java
下面我要簡述一下CommonJS、AMDCMD和ES6 Modulenode
在CommonJS中有一個全局的方法require(),能夠用於加載模塊。可是這個方法在瀏覽器端具備必定的侷限性,由於JavaScript是解釋性語言,從上而下直接執行。此時的困惑是es6
後來我獲得的答案:編程
最後個人筆記:
CommonJS是一種同步加載的方式,在服務器端模塊是存在本地的,這樣讀取時間很快,須要等待時間很短,能夠是同步加載,可是在瀏覽器端,依賴的模塊是存放在服務器端的,讀取的時間依賴網速,若是網速很差的話,須要等待好久。javascript就會報錯了,因此在瀏覽器端須要異步加載的方式瀏覽器
let num = 0 function add (a, b) { return a + b } module.exports = { num: num, add: add }
exports 和 module.exports的區別:Node爲每個模塊都提供了一個exports變量,指向module.exports。 服務器
以上的寫法module.export嘗試寫成:異步
// 結果報錯 let num = 0 function add (a, b) { return a + b } exports = { num: num, add: add }
第二種寫法:編程語言
// 結果成功 let num = 0 function add (a, b) { return a + b } exports.num = num exports.add = add
node中,exports指向module.exports。若是直接將一個對象賦值給exports,那麼exports原先指向module.exports會被破壞,這樣這兩種之間就沒有聯繫了,就會報錯。若是非要想用exports的話,能夠直接給exports添加屬性。
let math = require('./math')
// 所有加載 import * as util from 'xxx' import AA from 'yyy' // 按需加載 import { A, B } from 'xxx'
import * as aa from 'xxx'的語法,會將xxx文件內export的函數整合成一個對象。
import AA from 'yyy',引入的是export default的函數
import 在編輯時就執行的,因此:
foo() import { foo } from 'xxx'
不會報錯,由於import { foo } from 'xxx'在編輯時就執行了,foo()是在運行時才執行。
import命令是在編輯時就會執行的,因此沒法作到放到if代碼中或者函數中,
if (a) { import { foo } from 'xxx' } // 會報句法錯誤
import export只能在模塊的頂層,不能夠在代碼塊中,這樣就沒法實現運行時動態加載模塊(條件加載)。 => import()的出現
使用import()能夠相似node裏的require(),能夠動態加載且import()是異步加載。import()加載模塊成功之後,這個模塊會做爲一個對象當then方法的參數。
import('xxx').then(module => { ... })
export 規定的時對外的接口,必須模塊內部的變量創建一一對應關係。看到阮一峯大佬的內容裏有這麼一段:
目前仍是不很理解:爲何export var m = 1 或者export function aa (){}就能夠創建一一對應的關係。
以前一直沒有考慮過他們以前的區別,今天又仔細研讀了一下阮一峯的es6關於模塊的講解,以爲說的很好。
ES6的設計思想是儘可能的靜態化,在編譯時就能夠肯定模塊之間的依賴關係,以及輸出和輸入的變量
CommonJS、AMD、CMD只能在運行時才能夠肯定模塊之間的加載關係。
// CommonJS let { stat, exists, readFile } = require('fs'); // ES6 import { stat, exists, readFile } from 'fs';
第一個和第二的區別:
CommonJS是將fs模塊總體加載出來生成一個對象,而後在這個對象讀取裏找stat, exists, readFile方法,這種就是運行時加載
ES6模塊會只在fs中加載stat, exists, readFile這三個方法,不會加載其餘方法,這種就是編輯時加載