模塊化開發方便代碼的管理,提升代碼複用性,下降代碼耦合,每一個模塊都會有本身的做用域。當前流行的模塊化規範有CommonJS,AMD,CMD,ES6的import/export前端
簡單封裝 -> 命名空間/modules -> script loader/modules loader -> 同步加載CommonJS/AMD/CMD -> ES6 import export/export default -> 模塊打包工具browserify/webpacknode
用法:把不一樣的函數簡單地放在一塊兒,看做一個模塊
缺點:jquery
用法:把功能代碼放入對象中,看成對象的屬性
優勢:減小了全局上的變量數目,避免變量全局污染
缺點:本質是對象,而這個對象會暴露全部模塊成員,內部狀態能夠被外部改寫webpack
做用:建立一個獨立的做用域。數據是私有的, 外部只能經過暴露的方法操做
這個做用域裏面的變量,外面訪問不到(即避免「變量污染」)es6
導入導出:require & exports/module.exports
主要實踐者:NodeJSweb
模塊導入
語法:require(module)
數組
eg: var math = require('math'); math.add(2, 3);
若是模塊輸出的是一個函數,那就不能定義在exports對象上面,而要定義在module.exports變量上面。瀏覽器
// example2.js module.exports = function () { console.log("hello world") } // main.js require('./example2.js')()
提倡依賴前置,在定義模塊的時候就要聲明其依賴的模塊。在requireJs推廣過程當中產生的規範服務器
模塊定義define(id?, dependencies?, factory)
id:字符串,模塊名稱(可選)
dependencies:數組,是咱們要載入的依賴模塊(可選),使用相對路徑
factory:工廠方法,返回一個模塊函數babel
模塊導入require([module], callback)
module:是一個數組,裏面的成員就是要加載的模塊
callback:則是加載成功以後的回調函數
requireJS 優勢
採用異步方式加載模塊,經過define來定義一個模塊,經過require來引入模塊,模塊的加載不影響後面語句的執行,全部依賴於這些模塊的語句都寫在一個回調函數中,加載完畢後,這個回調函數才運行
提倡就近依賴(按需加載),在用到某個模塊的時候再去require進來。在Sea.js推廣過程當中產生的規範
模塊定義 define(id?, dependencies?, factory)
與AMD相似
// eg define('hello', ['jquery'], function(require, exports, module) { // 模塊代碼 // return 模塊對象 });
模塊導入導出
與 AMD 相似
導入導出:import/export/export default
默認輸出是一個函數/變量
其餘模塊加載該模塊時,import命令能夠爲該匿名函數指定任意名字
須要注意的是,這時import命令後面,不使用大括號
// export-fn.js export default function () { console.log('foo'); } import foo from 'export-fn.js'
export default命令也能夠用在非匿名函數前,視同匿名函數加載
export default 命令用於指定模塊的默認輸出。一個模塊只能有一個默認輸出,所以export default 命令只能使用一次。因此,import命令後面纔不用加大括號,由於只可能惟一對應export default命令。
本質上,export default就是輸出一個叫作default的變量或方法,而後系統容許你爲它取任意名字
使用export default時,對應的import語句不須要使用大括號,默認輸出
使用export時,對應的import語句須要使用大括號
// 第一組 export default export default function crc32() { // 輸出 // ... } import crc32 from 'crc32'; // 輸入 // 第二組 export export function crc32() { // 輸出 // ... }; import {crc32} from 'crc32'; // 輸入
ES6模塊使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。
CommonJS 和 AMD 模塊,都只能在運行時肯定這些東西;
CommonJS 模塊就是對象,輸入時必須查找對象屬性
CommonJS模塊
let { stat, exists, readFile } = require('fs')
總體加載fs模塊(即加載fs的全部方法),生成一個對象(_fs),而後再從這個對象上面讀取 3 個方法。這種加載稱爲「運行時加載」
ES6模塊
import { stat, exists, readFile } from 'fs'
從fs模塊加載 3 個方法,其餘方法不加載,這種加載稱爲「編譯時加載」或者靜態加載
CommonJS模塊
const path = './' + fileName const myModual = require(path)
動態加載,require到底加載哪個模塊,只有運行時才知道
動態加載,正在提案階段,import()返回一個 Promise 對象
import()加載模塊成功之後,這個模塊會做爲一個對象,看成then方法的參數
import()相似於 Node 的require方法,區別主要是前者是異步加載,後者是同步加載。
適用場景
(1)按需加載
(2)條件加載
(3)動態的模塊路徑
注:關於ES6模塊化,詳細見 阮一峯的es6入門 module模塊
require/exports是CommonJS的一部分;import/export是ES6的新規範
require支持 動態導入,import不支持,正在提案 (babel 下可支持)
require是 同步 導入,import屬於 異步 導入
require是 值拷貝,導出值變化不會影響導入值;import是值引用,指向 內存地址,導入值會隨導出值而變化