生活随笔
收集整理的這篇文章主要介紹了
                                
【重要】ES6-23 JavaScript模块化
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
 
                                
                            
                            
                            -  前端js模塊化的演變發展
 -  模塊化解決的問題
 -  傳統模塊化、插件化
 -  CommonJS
 -  AMD/CMD
 -  ES6模塊化
 
 
 ES6以前 沒有js引擎
 一開始js寫在html的script標簽里js內容增多,抽取出index.js文件,外部引入js再增加,index.html對應index.js index2.html對應index2.js(模塊化概念的誕生)含有可復用的代碼,提出公共的common.js引入common.js的所有內容不合理 → 不能光以頁面為基準來區分程序塊、分js文件 
 
案例一 模塊化初試
 
<!DOCTYPE html
>
<html lang
="en">
<head
><meta charset
="UTF-8"><meta http
-equiv
="X-UA-Compatible" content
="IE=edge"><meta name
="viewport" content
="width=device-width, initial-scale=1.0"><title
>Document
</title
>
</head
>
<body
><script type
="text/javascript" src
="js/module_a.js"></script
><script type
="text/javascript" src
="js/module_b.js"></script
><script type
="text/javascript" src
="js/module_c.js"></script
><script type
="text/javascript" src
="js/index.js"></script
>
</body
>
</html
>
 
var a 
= [1, 2, 3, 4, 5].reverse()
 
var b 
= a
.concat([6, 7, 8, 9, 10])
 
var c 
= b
.join('-')
 
console
.log(a
)
console
.log(b
)
console
.log(c
)
 
 
存在問題
 
- js引擎遇到script時阻塞,所以這4個js文件必須按內部的邏輯,順序加載,順序是不能變的
 - 這4個文件共用了JS作用域-全局作用域
 - 因此:污染全局 + if 變量重名 → 變量覆蓋
 
 
 模塊化解決問題:
 加載順序污染全局 
 
案例二 IIFE注入
 
 歷史問題:ECMA規定語句應當以分號結尾,早前js都是運行在瀏覽器上的,但瀏覽器支持判斷當前是否是語句,是就自動加上分號。當使用多個IIFE,且不寫分號時,瀏覽器無法識別,報錯。因此約定俗成的規定,IIFE前面必須寫分號,更規范的是結尾也寫分號,即
 ;(function(){
 })();
 
 
使用IIFE,解決污染全局,為了易于拓展,模塊應當返回對象新的問題,若沒有拋到全局,如何在模塊之間獲得相應的abc用變量接收IIFE的返回值,在需要用的的模塊傳入(注入),解決了模塊依賴注意:模塊名完全獨立,不應該重復,因此在全局聲明了,而內部abc屬于數據類型的變量,不能在全局聲明注意:不注入moduleABC,直接用moduleA.a訪問變量能得到正確結果,但注入意味著moduleABC被引入到局部作用域下,不再需要去全局上查找了 
var moduleA 
= (function () {var a 
= [1, 2, 3, 4, 5].reverse()return {a
: a
}
})();
 
var moduleB 
= (function (moduleA) {var b 
= moduleA
.a
.concat([6, 7, 8, 9, 10])return {b
: b
}
})(moduleA
);
 
var moduleC 
= (function (moduleB) {var c 
= moduleB
.b
.join('-')return {c
: c
}
})(moduleB
);
 
; (function (moduleA, moduleB, moduleC) {console
.log(moduleA
.a
)console
.log(moduleB
.b
)console
.log(moduleC
.c
)
})(moduleA
, moduleB
, moduleC
);
 
存在問題
 
順序問題依然未解決 
插件
 
構造函數執行init構造函數掛載到window(插件)script里實例化
 
  
 
案例三 CommonJS
 
 NodeJS誕生帶來了前所未有的模塊化體驗
 require(...) 引入模塊
 module.exports導出模塊
 
 
運行在node環境下
 
 CommonJS是模塊化規范,來源于NodeJS
 在服務端開發,引入模塊用require,是同步的方法
 只要引用,就會創建模塊的實例
 有非常強的緩存機制
 一定是在Node上運行,客戶端運行不了(要借助webpack?)
 require實質是IIFE,會傳入一些參數
 (function(exports,require,module,__filename.__dirname){})()
 
 
 
<!DOCTYPE html
>
<html lang
="en">
<head
><meta charset
="UTF-8"><meta http
-equiv
="X-UA-Compatible" content
="IE=edge"><meta name
="viewport" content
="width=device-width, initial-scale=1.0"><title
>Document
</title
>
</head
>
<body
><script type
="text/javascript" src
="index.js"></script
>
</body
>
</html
>
 
var a 
= (function () {return [1, 2, 3, 4, 5].reverse()
})();
module
.exports 
= {a
};
 
var moduleA 
= require('./module_a')
var b 
= (function () {return moduleA
.a
.concat([6, 7, 8, 9, 10])
})();
module
.exports 
= {b
}
 
var moduleB 
= require('./module_b')
var c 
= (function () {return moduleB
.b
.join('-')
})();
module
.exports 
= {c
: c
}
 
var moduleA 
= require('./js/module_a.js');
var moduleB 
= require('./js/module_b.js');
var moduleC 
= require('./js/module_c.js');
; (function () {console
.log(moduleA
.a
)console
.log(moduleB
.b
)console
.log(moduleC
.c
)
})()
 
案例四 AMD
 
- 不需要借助webpack就能運行在客戶端
 - 所有依賴加載完成后才會執行回調函數(前置依賴)
 
 
 AMD Asynchronous Module Definition 異步模塊定義
 來源于CommonJS
 define(moduleName, [module], factory) 定義模塊
 require([module], callback) 引入模塊
 RequireJS實現AMD
 
 
引入require.js定義+使用依賴時注入使用module得先require.config配置路徑 
<!DOCTYPE html
>
<html lang
="en">
<head
><meta charset
="UTF-8"><meta http
-equiv
="X-UA-Compatible" content
="IE=edge"><meta name
="viewport" content
="width=device-width, initial-scale=1.0"><title
>Document
</title
>
</head
>
<body
><script src
="js/require.js"></script
><script src
="js/index.js"></script
>
</body
>
</html
>
 
define('moduleA', function () {var a 
= [[1, 2, 3, 4, 5]]return {a
: a
.reverse()}
}) 
define('moduleB', ['moduleA'], function (moduleA) {return {b
: moduleA
.a
.concat([6, 7, 8, 9, 10])}
}) 
define('moduleC', ['moduleB'], function (moduleB) {return {c
: moduleB
.b
.join('-')}
})
 
require
.config({paths
: {moduleA
: 'js/module_a',moduleB
: 'js/module_b',moduleC
: 'js/module_c'}
})
require(['moduleA', 'moduleB', 'moduleC'], function (moduleA, moduleB, moduleC) {console
.log(moduleA
.a
)console
.log(moduleB
.b
)console
.log(moduleC
.c
)
});
 
案例五CMD
 
- 阿里對模塊化的貢獻
 - require加載 define定義
 - exports導出(return和它的效果一直) module操作
 - 需要配置模塊URL
 - 依賴加載完畢后執行factory
 - 依賴就近 按需加載(這是和CommonJS AMD本質上的不同)
 
 
 Common Mudule Definition 通用模塊定義
 define(function(require,exports,module){}) 定義模塊
 seajs.use([module路徑],function(moduleA,moduleB,moduleC){}) 使用模塊
 
 
<!DOCTYPE html
>
<html lang
="en">
<head
><meta charset
="UTF-8"><meta http
-equiv
="X-UA-Compatible" content
="IE=edge"><meta name
="viewport" content
="width=device-width, initial-scale=1.0"><title
>Document
</title
>
</head
>
<body
><script src
="js/sea.js"></script
><script src
="js/index.js"></script
>
</body
>
</html
>
 
define(function (require, exports, module) {var a 
= [[1, 2, 3, 4, 5]]return {a
: a
.reverse()}
})
 
define(function (require, exports, module) {var moduleA 
= require('module_a')return {b
: moduleA
.a
.concat([6, 7, 8, 9, 10])}
})
 
define(function (require, exports, module) {var moduleB 
= require('module_b')return {c
: moduleB
.b
.join('-')}
})
 
seajs
.use(['module_a.js', 'module_b.js', 'module_c.js'], function (moduleA, moduleB, moduleC) {console
.log(moduleA
.a
)console
.log(moduleB
.b
)console
.log(moduleC
.c
)
})
 
案例六 ES6模塊化規范
 
 import module from ‘模塊路徑’ 導入模塊
 export module 導出模塊
 Uncaught SyntaxError: Cannot use import statement outside a module
 
 
調試過程中的報錯解答
 
<!DOCTYPE html
>
<html lang
="en">
<head
><meta charset
="UTF-8"><meta http
-equiv
="X-UA-Compatible" content
="IE=edge"><meta name
="viewport" content
="width=device-width, initial-scale=1.0"><title
>Document
</title
>
</head
>
<body
><script type
="module" src
="./js/index.js"></script
>
</body
>
</html
>
 
export default {a
: [1, 2, 3, 4, 5].reverse()
}
 
import moduleA 
from './module_a.js'
export default {b
: moduleA
.a
.concat([6, 7, 8, 9, 10])
}
 
import moduleB 
from './module_b.js'
export default {c
: moduleB
.b
.join('-')
}
 
import moduleA 
from './module_a.js'
import moduleB 
from './module_b.js'
import moduleC 
from './module_c.js'; (function (moduleA, moduleB, moduleC) {console
.log(moduleA
.a
)console
.log(moduleB
.b
)console
.log(moduleC
.c
)
})(moduleA
, moduleB
, moduleC
);
 
案例7 CommonJS與ES6的區別
 
 
exports
.a 
= 0;
setTimeout(() => {console
.log('來自export', ++exports
.a
)
}, 300);
 
const { a 
} = require('./export')
setTimeout(() => {console
.log('來自commonjs', a
)
}, 300); 
import { a 
} from './export'
setTimeout(() => {console
.log('來自es6', a
) 
}, 300);
 
 
commonjs輸出的是一個值的拷貝es6模塊輸出的是值的引用commonjs模塊是在運行時加載(commonjs運行在服務端,require時加載)es6模塊是在編譯時加載 
YUI
                            總結
                            
                                以上是生活随笔為你收集整理的【重要】ES6-23 JavaScript模块化的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                            
                                如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。