模塊化的學習和理解

最近在看vue源碼,而後看到了rollup,而後又看到了模塊化的概念,因此對模塊化的概念進行一個學習和總結。如下就是個人學習成果,若是有什麼不對的歡迎指教。javascript

模塊化概念

模塊化存在的意義:開發者但願在開發過程當中只須要關注本身的核心業務邏輯,其餘的能夠直接加載別人寫好的模塊。可是Javascript不是一種模塊化編程語言,在es6之前,它是不支持」類」(class),因此也就沒有」模塊」(module)了(借鑑而來)vue

nodejs一個應用於服務器端編程被提出時,Javascript模塊化也所以誕生,CommonJS模塊規範被提出。在es6模塊以前,CommonJS統一了模塊化編程。java

下面我要簡述一下CommonJS、AMDCMD和ES6 Modulenode

同步加載 CommonJS

在CommonJS中有一個全局的方法require(),能夠用於加載模塊。可是這個方法在瀏覽器端具備必定的侷限性,由於JavaScript是解釋性語言,從上而下直接執行。此時的困惑是es6

圖片描述

後來我獲得的答案:
圖片描述編程

最後個人筆記:
CommonJS是一種同步加載的方式,在服務器端模塊是存在本地的,這樣讀取時間很快,須要等待時間很短,能夠是同步加載,可是在瀏覽器端,依賴的模塊是存放在服務器端的,讀取的時間依賴網速,若是網速很差的話,須要等待好久。javascript就會報錯了,因此在瀏覽器端須要異步加載的方式瀏覽器

module.exports和exports 模塊導出

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添加屬性。

require 模塊導入

let math = require('./math')

異步加載

  • AMD/RequireJS 異步加載 依賴前置、提早執行
  • CMD/sea.js 異步加載 依賴就近、延遲加載

ES6 Module

import 導入

常見用法:

// 所有加載
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()

import命令是在編輯時就會執行的,因此沒法作到放到if代碼中或者函數中,

if (a) {
    import { foo } from 'xxx'
}
// 會報句法錯誤

import export只能在模塊的頂層,不能夠在代碼塊中,這樣就沒法實現運行時動態加載模塊(條件加載)。 => import()的出現
使用import()能夠相似node裏的require(),能夠動態加載且import()是異步加載。import()加載模塊成功之後,這個模塊會做爲一個對象當then方法的參數。

import('xxx').then(module => {
    ...
})

export 暴露模塊

export 規定的時對外的接口,必須模塊內部的變量創建一一對應關係。看到阮一峯大佬的內容裏有這麼一段:

圖片描述

目前仍是不很理解:爲何export var m = 1 或者export function aa (){}就能夠創建一一對應的關係。

CommonJS和ES6 Module的區別

以前一直沒有考慮過他們以前的區別,今天又仔細研讀了一下阮一峯的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這三個方法,不會加載其餘方法,這種就是編輯時加載

相關文章
相關標籤/搜索