寫了十年JS殊不知道模塊化爲什麼物?

模塊化這個問題並不是一開始就存在,WWW剛剛問世的時候,html,JavaScript,CSS(JS和CSS都是後來在網景被引進瀏覽器的)都是極其簡單的存在,不須要模塊化。css

模塊化的需求是規模的產物,當web page進化到web application,瀏覽器端處理的邏輯愈來愈複雜,展示的樣式和動畫越來多,對於工程的要求也就愈來愈高。因而模塊化的需求也就產生了。模塊化的意義:html

  • 組件的複用,下降開發成本和維護成本
  • 組件單獨開發,方便分工合做
  • 模塊化遵循標準,方便自動化依賴管理,代碼優化,部署

JavaScript長久以來被認爲是簡單的腳本語言,實際上狀況早就發生來變化,在最新版的JavaScript是通用編程語言而不是腳本語言。腳本語言,好比shell並非用來完成複雜功能的,只是用來作一些自動化控制,是不須要模塊化的。而用於構建複雜系統通用編程語言(好比Java)通常都有模塊的實現。前端

1.模塊化標準

ES6以前,JavaScript並無原生的模塊機制,好在JavaScript很是靈活,有不少種寫法能夠將代碼自然隔離,起到模塊化的功能:vue

//define

var  modules  =  {}  

modules.mod1  =  {  

  foo  :  function(){...},

  bar  :  function(){...}

  ...

}     //歡迎加入前端全棧開發交流圈一塊兒學習交流:1007317281

//call

modules.mod1.foo()

複製代碼

在客戶端這種方式基本是夠用的,然而問題依然存在:你沒法管理依賴,全部的代碼都必須load到內存中,須要哪些模塊必須由人工處理。分模塊是工程化的產物,也是天然發展的結果,天然有不少嘗試。很顯然,模塊之間互相依賴須要編寫模塊的時候遵循必定的規範。現存的規範還真很多,不知道ES6 可否終結這場混戰:node

  • AMD
  • CMD
  • closure
  • CommonJS
  • ES6

AMD和CMD分別是requireJS和seaJS定義的標準。使用純原生的ES5語法意味者其只能使用閉包,書寫和閱讀都很怪異。值得一提的是AngularJS也使用相似的方式,以致於Angular的做者們都受不了,決定在AngularJS 2 使用新的語言AtScript,前端輪子太多,又造了一個,好在這個輪子造的比較好,兼容ES6 TypeScript規範,扯的遠了,看看AMD長得啥樣:webpack

AMD:es6

define(['./a',  './b'],  function(a,  b)  {  

  ...

})
複製代碼

Closure是google出品的前端工具,Closure提供了一系列工具和庫,谷歌本身的多個項目都是使用Closure開發的。closure compiler經過模塊間依賴的聲明把全部被依賴的文件打包到一塊兒,並且Closure的一大優點是若是採用破壞性壓縮(ADVANCED)壓縮率極高。web

//文件A

goog.provide('module1')  

com.foo.bar  =  {  

 ...

}     //歡迎加入前端全棧開發交流圈一塊兒學習交流:1007317281

//文件B

goog.require('module1')  

var  a  =  com.foo.bar;
複製代碼

然而Closure並不完美,不一樣的文件共享同一個全局對象,因此你不得不這樣寫 a.b.c=...。面試

CommonJS是Node.js使用的模塊化標準。Node.js對於前端開發者來講不只僅能夠提供一個Server,仍是一個完美的開發平臺,在Node上使用Grunt/gulp構建web項目是件很爽的事情。Node的模塊化聲明的方式與Closure相似,只是更進一步,自然隔離了命名空間。上面的代碼若是使用CommonJS的模塊化規範能夠這麼寫shell

//文件A

module.exports  =  {...}  

//文件B

var  a  =  require('./foo/bar')

複製代碼

browserify讓使用CommonJS模塊化規範的代碼能夠運行在客戶端上。

2.靜態加載與動態加載

在看ES6以前咱們先看模塊加載的兩種方式:

  • 靜態加載:在編譯階段進行,把全部須要的依賴打包到一個文件中
  • 動態加載:在運行時加載依賴

AMD標準是動態加載的表明,而CommonJS是靜態加載的表明。AMD的目的是用在瀏覽器上,因此是異步加載的。而NodeJS是運行在服務器上的,同步加載的方式顯然更容易被人接收,因此使用了CommonJS。一樣的道理,若是靜態加載,那就使用同步的加載方式,若是動態加載就必須用異步的加載方式。

那麼ES6採用何種加載機制?

ES6既但願用簡單的聲明方式來完成靜態加載,又不肯放棄動態加載的特性,而這兩種方式幾乎不可能簡單的同時實現,因此ES6提供了兩種獨立的模塊加載方法。

2.1 聲明的方式

import  {foo}  from module1
複製代碼

2.2 經過System.import API的方式

System.import('some_module')  

    .then(some_module  =>  {

        // Use some_module

    })

    .catch(error  =>  {

        ...

    });           //歡迎加入前端全棧開發交流圈一塊兒學習交流:1007317281
複製代碼

再看下export的語法,與CommonJS很像,只不過沒有了module這個對象,而直接調用export。 能夠export任何一個 函數,變量,對象

//expt.js

export function  abc(){}//export 一個命名的function  

export default  function(){}  //export default function  

export num=123  //export 一個數值  

export obj={}  

export  {  obj as  default  };

//import

import expt from  'expt'//default export  

import  {default  as  myModule}  from  'expt'  //rename  

import  {abc,num,obj}  from  'expt'
複製代碼

目前來看,使用預編譯的方式顯然要好於使用動態加載,瀏覽器對ES6語法支持還不好,若是使用動態加載ES6,在瀏覽器端要作ES6到ES5的翻譯工做,這個顯然是重複低效的。可是隨着瀏覽器對ES6支持加強,尤爲是瀏覽器實現了動態加載API後,動態加載的優點就會展示:

  • 更流暢的用戶體驗,動態加載能夠實現相似lazyload的加載方式,將download的時間分散
  • 更簡潔的項目,無需預編譯,項目能夠少配置不少工具
  • HTTP/2的普及更傾向於使用多個小的請求,適合動態加載

3.實踐

若是如今使用ES6,能夠選擇動態加載模塊system.js 或者browserify的預編譯方法。

使用system.js+babel動態加載依賴。system.js 是ES6動態模塊加載的一個實現。寫了一個小DEMO:

項目初始化

bower install babel system.js  --save
index.html
    <script src="/bower_components/system.js/dist/system.js"></script>

    <script>

      System.config({

          baseURL  :  "/scripts",

          transpiler  :  'babel',

          map  :  {

            babel:'/bower_components/babel/browser.js'

          }

        }             //歡迎加入前端全棧開發交流圈一塊兒學習交流:1007317281

      )

      System.import('main.js').then(function(m){

        m.default.sayHello()

      })

    </script>
main.js

export  default  {  

  sayHello  :  function(){

    console.log('hello')

  }

}

複製代碼

使用gulp+browserify+babel預編譯。gulp是一個Node.js平臺上的任務管理平臺。預編譯要作不少配置,很是繁瑣,推薦使用yeoman來生成項目骨架。好比使用generator-es6-webapp。

生成很是簡單,在項目目錄中執行

yo es6-webapp
複製代碼

缺乏依賴的化安裝依賴就好。

4.其餘,關於前端化趨勢

ES6模塊化意味着什麼?

更強大的前端,Web技術總體前移。HTML5的發展和某些優秀瀏覽器的支持讓web技術總體前移,之前像渲染這種工做在後端進行是因爲瀏覽器薄弱,且有老IE這種拖後腿搗亂的選手。

簡化編程模型,人工管理JS依賴和將多個JS打包這種工做能夠不須要了,而配合WebComponents標準,開發Web將再也不借助模板引擎和預編譯引擎。

前端化還有更深遠的影響--在過去瀏覽器是個工具,如今瀏覽器是個重要的工具,在將來瀏覽器就是用戶惟一的操做系統。

感謝您的觀看,若有不足之處,歡迎批評指正。 獲取資料👈👈👈 本次給你們推薦一個免費的學習羣,裏面歸納移動應用網站開發,css,html,webpack,vue node angular以及面試資源等。 對web開發技術感興趣的同窗,歡迎加入Q羣:👉👉👉1007317281👈👈👈,無論你是小白仍是大牛我都歡迎,還有大牛整理的一套高效率學習路線和教程與您免費分享,同時天天更新視頻資料。 最後,祝你們早日學有所成,拿到滿意offer,快速升職加薪,走上人生巔峯。

相關文章
相關標籤/搜索