這篇文章,咱們將瞭解爲何JS社區有必要選擇ES6模塊。html
要明白這種重要性,首先咱們須要描述一下JS的實際狀況。過去5年,JavaScript 發展得很是迅猛,大多數開發人員幾乎沒意識到當前已經有 5
種方式,能夠爲 JavaScript 腳本和應用建立模塊了!前端
IIFE
實現的簡單模塊化示例:const myModule = (function (...deps){ // JavaScript chunk return {hello : () => console.log(‘hello from myModule’)}; })(dependencies);
相信你們對這段代碼都不陌生,它只是把變量和方法都封裝在自己做用域內的一種普通模式。其存在的缺點就是沒有幫咱們處理依賴。node
<pre>define(‘myModule’, [‘dep1’, ‘dep2’], function (dep1, dep2){ // JavaScript chunk, with a potential deferred loading return {hello: () => console.log(‘hello from myModule’)}; }); // anywhere else require([‘myModule’], function (myModule) { myModule.hello() // display ‘hello form myModule’ });
效率高,惋惜有點冗長,並且不能在 Node.js 本地運行。es6
// file1.js modules.export = { hello : () => console.log(‘hello from myModule’) } // file2; const myModule = require('./file1.js'); myModule.hello();
感受這種方式更酷吧,不只能夠定義變量的做用域,還能夠定義模塊之間的依賴。惋惜這是專爲 Node
設計的,不支持在瀏覽器運行,也不能異步加載模塊。可是,它能夠在前端app使用,藉助 Browserify
或者其餘工具來轉換,就可讓它在瀏覽器運行了。瀏覽器
UMD 就來嘗試解決這個問題了。它經過把 AMD 和 CommonJS 結合起來,使之在各類需求下都是可集成的,代碼大概以下:服務器
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory() : typeof define === 'function' && define.amd ? define(factory) : (factory()); }(this, function () { // JavaScript chunk return { hello : () => console.log(‘hello from myModule’) } });
該模式根據內容來判斷選擇 AMD 仍是 CommonJS. 這種模式對於打包 多環境
的庫,如 lodash
或者 moment.js
是十分適合的。app
首先,這些解決方案沒有一個是由TC39團隊定義的標準。ECMA6 如今已經被大量的開發者所使用,那爲什麼不選擇該版本JS定義的標準(ES6模塊)呢?異步
這個標準提供了一個更加靈活有力的解決方式。我推薦你看這篇文章, 瞭解 ES6模塊的所有屬性,由於這篇文章,我把重點放在了ES6模塊這個性質上。它可以更加精確地定義模塊間哪些須要被 exposed/imported
。一塊兒看看下面的代碼:模塊化
// file1.js const f1 = ()=> console.log(‘f1’); const f2 = ()=> console.log(‘f2’); const f3 = ()=> console.log(‘f3’); export {f1, f2, f3}; // file2.js import {f1, f2} from 「./file1」; f1(); // display ‘f1’ f2(); // display ‘f2’
從這裏能夠看出,只須要靜態地聲明咱們想要 import
的內容就能夠。與其它模式不一樣,像 CommonJS 咱們能夠動態加載須要的文件。若是咱們在 CommonJS 裏面使用這個例子,就會有點不一樣:工具
// file1.js const f1 = ()=> console.log(‘f1’); const f2 = ()=> console.log(‘f2’); const f3 = ()=> console.log(‘f3’); modules.exports = {f1,f2,f3}; // file2.js const file1 = require(‘./file1’); file1.f1(); // display ‘f1’ file1.f2(); // display ‘f2’ file1[process.ENV.funcName]();
很明顯,最後一行沒法呈現成真正的代碼,但它代表了一些值超出了可控範圍,沒法在靜態分析中被預知。這裏,咱們實質上是能夠調用 f3
,由於用 CommonJs
(AMD、IIFE 或者 UMD) 咱們都是沒法限制 import
的內容。
因此?瞭解代碼的靜態分析是使用什麼是否是也很重要呢?
答案是確定的!
由於有了這個控制,開發者工具能夠檢測到一些 bug。 若是你使用 WebPack 2 或者 Rollup.js 將會更有趣,結合 Tree Shaking
, 你編譯的文件將會更小。Tree Shaking
的功能就是把不用用到的代碼移除掉。
這就是 tree shaking
的一個例子 :
//------------- // main.js import {cube} from './maths.js'; console.log( cube( 5 ) ); // 125 //------------- // maths.js export function square ( x ) { return x * x; } // This function gets included export function cube ( x ) { return x * x * x; }
function cube ( x ) { return x * x * x; } console.log( cube( 5 ) ); // 125
Mathieu Breton CTO chez JS-Republic