這是我參與8月更文挑戰的第8天,活動詳情查看:8月更文挑戰前端
優勢
:模塊化
就是將系統分離成獨立功能的模塊,這樣咱們須要什麼功能,就加載什麼功能。web
模塊化的優勢
:編程
CommonJS(服務端)
=>AMD(瀏覽器)
=> CMD
=> ES6 Module模塊化
瀏覽器
前端模塊規範有三種:CommonJs,AMD和CMD。
CommonJs用在服務器端,AMD和CMD用在瀏覽器環境
AMD 是 RequireJS 在推廣過程當中對模塊定義的規範化產出。
CMD 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。\緩存
AMD:提早執行(異步加載:依賴先執行)+延遲執行
CMD:延遲執行(運行到需加載,根據順序執行)服務器
Node 應用由模塊組成,採用 CommonJS 模塊規範。markdown
每一個文件就是一個獨立模塊
,有本身的做用域
。在一個文件裏面定義的變量、函數、類,都是私有的
,對其餘文件不可見。網絡
主要分爲定義模塊和引入模塊兩個步驟。異步
定義模塊模塊化
CommonJS規範規定,每一個模塊內部,module
變量表明當前模塊。這個變量是一個對象,它的exports
屬性(即module.exports
)是對外的接口。加載某個模塊,實際上是加載該模塊的module.exports
屬性。
// 經過`module.exports`輸出變量`x`和函數`addX`
let x = 1;
let addX = function (value) {
return value + x;
};
module.exports.x = x;
module.exports.addX = addX;
複製代碼
引入模塊
require
方法用於加載模塊。
var example = require('./example.js');
複製代碼
CommonJS模塊的加載機制是,輸入的是被輸出的值的拷貝。也就是說,一旦輸出一個值,模塊內部的變化就影響不到這個值。
AMD規範全稱是Asynchronous Module Definition,即異步模塊加載機制,主要用於瀏覽器。它完整描述了模塊的定義,依賴關係,引用關係以及加載機制。因爲該規範不是原生js
支持的,使用AMD規範進行開發的時候須要引入第三方的庫函數,AMD對應的就是鼎鼎大名的RequireJS。
define和require這兩個定義模塊、調用模塊的方法,合稱爲AMD模式。它的模塊定義的方法很是清晰,不會污染全局環境,可以清楚地顯示依賴關係。
使用define
用來暴露模塊,使用require
用來引入模塊;require()異步加載模塊,瀏覽器不會失去響應;它指定的回調函數,只有前面的模塊都加載成功後,纔會運行,解決了依賴性的問題。
AMD模式能夠用於瀏覽器環境
,而且容許異步加載模塊
,也能夠根據須要動態加載模塊。
define方法用於定義模塊
,RequireJS要求每一個模塊放在一個單獨的文件裏。 按照是否依賴其餘模塊,能夠分紅兩種狀況討論。第一種狀況是定義獨立模塊
,即所定義的模塊不依賴其餘模塊;第二種狀況是定義非獨立模塊
,即所定義的模塊依賴於其餘模塊。
require方法用於調用模塊。它的參數與define方法相似。
RequireJS
主要解決了兩個問題:js
文件可能有依賴關係,被依賴的文件須要早於依賴它的文件加載到瀏覽器js
加載的時候瀏覽器會中止頁面渲染,加載文件越多,頁面失去響應時間越長CommonJS規範加載模塊是同步的,也就是說,只有加載完成,才能執行後面的操做。AMD規範則是非同步加載模塊,容許指定回調函數。因爲Node.js主要用於服務器編程,模塊文件通常都已經存在於本地硬盤,因此加載起來比較快,不用考慮非同步加載的方式,因此CommonJS規範比較適用。可是,若是是瀏覽器環境,要從服務器端加載模塊,這時就必須採用非同步模式,所以瀏覽器端通常採用AMD規範。
CMD(Common Module Definition) ,通用模塊定義,它解決的問題和AMD規範是同樣的,只不過在模塊定義方式和模塊加載時機上不一樣,CMD也須要額外的引入第三方的庫文件,SeaJS
,SeaJS
推崇一個模塊一個文件
(對於模塊的引入,具備同步和異步兩中方式)
define
是一個全局函數,用來定義模塊
SeaJS
提供了seajs.use
來加載模塊
SeaJS的出現,是CommonJS在瀏覽器的踐行者,並吸取了RequireJS的優勢
ES6 規範只支持靜態的導入和導出,ES Module 須要在編譯時期進行模塊靜態優化,也就是必需要在編譯時就能肯定。
爲何要這麼作,主要是兩點:
export
和import
export
用於暴露接口,import
用於引入模塊在使用 ES Module 值得注意的是:import 和 export 命令只能在模塊的頂層,在代碼塊中將會報錯,這是由於 ES Module 須要在編譯時期進行模塊靜態優化,import 和 export 命令會被 JavaScript 引擎靜態分析,先於模塊內的其餘語句執行,這種設計有利於編譯器提升效率,但也致使沒法在運行時加載模塊(動態加載)。
對於這個缺點,TC39 有了一個新的提案 – Dynamic Import,提案的內容是建議引入 import()
方法,實現模塊動態加載。
// specifier: 指定所要加載的模塊的位置
import(specifier)
複製代碼
它是運行時執行,也就是說,何時運行到這句話,就會加載到指定的模塊。另外,import()函數所加載的模塊沒有靜態連接關係,這點也是與import語法不一樣
模塊定義時對依賴的處理不一樣
AMD推崇前置依賴,在定義模塊時就要聲明其依賴的模塊;而CMD推從就近依賴,只有在用到某個模塊時再使用require導入;
對依賴模塊的處理機制不一樣
首先AMD和CMD對模塊的加載方式都是異步的 不過區別在於AMD當加載了依賴模塊以後當即執行依賴模塊,依賴模塊的執行順序和咱們書寫的順序不必定一致; 而CMD加載完依賴模塊以後,並不會當即執行,等全部的依賴模塊都加載好以後,進入回到函數邏輯,遇到require語句的時候,才執行對應的模塊,這樣模塊的執行順序就和咱們書寫的時候一致了
CommonJS時運行時加載
,由於ComminJS加載是先加載整個模塊,生成一個對象
(這個對象包含了path這個模塊的全部API),而後再從這個對象上面讀取方法-----運行時加載 ES6是編譯時加載
,ES6模塊不是對象
,它的對外接口只是一種靜態定義,在代碼靜態定義階段就會生成-----編譯時加載
//ES6模塊
import { basename, dirname, parse } from 'path';
//CommonJS模塊
let { basename, dirname, parse } = require('path');
複製代碼
以上這種寫法與CommonJS的模塊加載有什麼不一樣?
模塊化
就是將系統分離成獨立功能的模塊,這樣咱們須要什麼功能,就加載什麼功能。
模塊化的優勢
:
JS模塊化發展產物:CommonJS(服務端)
=>AMD(瀏覽器)
=> CMD
=> ES6 Module模塊化
CommonJs主要用在服務器端,AMD和CMD用在瀏覽器環境 AMD 是 RequireJS 在推廣過程當中對模塊定義的規範化產出。 CMD 是 SeaJS 在推廣過程當中對模塊定義的規範化產出。 ES6 規範只支持靜態的導入和導出,與CommonJS 的運行時加載
不一樣的是ES6是編譯時加載
,ES Module 是在編譯時期進行模塊靜態優化。
若是這篇文章幫到了你,記得點贊👍收藏加關注哦😊,但願點贊多多多多...
文中若有錯誤,歡迎在評論區指正