天天看點

CommonJs、AMD、CMD、WebpackAMD:

CommonJs:

        CommonJS是一個偏向于伺服器端的規範。CommonJS的一個子產品就是一個腳本檔案。require指令第一次加載該腳本時就會執行整個腳本,然後在記憶體中生成一個對象。nodejs和webpack都采用這種規範編寫代碼。

 常用的屬性:

{ id: '...',

    exports: { ... },

    loaded: true, ...

}

        id是子產品名,exports是該子產品導出的接口,loaded表示子產品是否加載完畢。此外還有很多屬性,這裡省略了。

        以後需要用到這個子產品時,就會到exports屬性上取值。即使再次執行require指令,也不會再次執行該子產品,而是到緩存中取值。

             CommonJS子產品規範主要分為三部分:子產品引用、子產品定義、子產品辨別。

       CommonJS子產品規範的好處

            CommonJS子產品規範很好地解決變量污染問題,每個子產品具有獨立空間,互不幹擾,命名空間相比之下就不太好。

            CommonJS規範定義子產品十分簡單,接口十分簡潔。

            CommonJS子產品規範支援引入和導出功能,這樣可以順暢地連接配接各個子產品,實作彼此間的依賴關系。

        node.js和webpack都是根據commonJs來編寫代碼的。

    優點:

        在後端,JavaScript的規範遠遠落後并且有很多缺陷,這使得難以使用JavaScript開發大型應用。比如:

  1. 沒有子產品系統
  2. 标準庫較少
  3. 沒有标準接口
  4. 缺乏包管理系統
  5. 清單内容

        CommonJS規範的提出,主要是為了彌補JavaScript沒有标準的缺陷,已達到像Python、Ruby和Java那樣具備開發大型應用的基礎能力,而不是停留在開發浏覽器端小腳本程式的階段

缺點:        

沒有并行加載機制

由于CommonJS是同步加載子產品,這對于伺服器端是很不好的,因為所有的子產品都放在本地硬碟。等待子產品時間就是硬碟讀取檔案時間,很小。但是,對于浏覽器而言,它需要從伺服器加載子產品,涉及到網速,代理等原因,一旦等待時間過長,浏覽器處于”假死”狀态。

是以浏覽器端不是很适合Common.Js,出現另一種規範AMD

AMD:

     是一個異步子產品定義規範;是RequireJs推廣過程中對子產品定義的規範化産出;

        1、提前執行。

        2、AMD推崇依賴前置,在定義子產品的時候就要聲明其依賴的子產品。

        3、AMD使用者體驗好,因為沒有延遲,依賴子產品提前執行了。

CMD:

    是一個通用子產品定義規範;是SeaJs推廣過程中對子產品定義的規範化産出;

        1、延遲執行

        2、CMD推崇依賴就近,隻有在用到某個子產品的時候才會去require

        3、CMD性能好,因為隻有使用者需要的時候才執行。

        AMD在加載子產品完成後就會執行更改子產品,所有子產品都加載執行完後會進入require的回調函數,執行主邏輯,這樣的效果就是依賴子產品的執行順序和書寫順序不一定一緻,看網絡速度,哪個先下載下傳下來,哪個先執行,但是主邏輯一定在所有依賴加載完成後才執行。

        CMD加載完某個依賴子產品後并不執行,隻是下載下傳而已,在所有依賴子產品加載完成後進入主邏輯,遇到require語句的時候才執行對應的子產品,這樣子產品的執行順序和書寫順序是完全一緻的。

這也是很多人說AMD使用者體驗好,因為沒有延遲,依賴子產品提前執行了,CMD性能好,因為隻有使用者需要的時候才執行的原因。

API角度AMD和CMD的差別:

        AMD 的 API 是一個當很多個用,CMD 的 API 嚴格區分,推崇職責單一。比如 AMD 裡,require 分全局 require 和局部 require,都叫 require。CMD 裡,沒有全局 require,而是根據子產品系統的完備性,提供 seajs.use 來實作子產品系統的加載啟動。CMD 裡,每個 API 都簡單純粹。

AMD和CommonJs的差別:

共同點:兩者都是為了實作子產品化程式設計而出現的,對于大型項目,參與人數多,代碼邏輯複雜,是最适合使用子產品化的思想來完成整個項目的。同時采用這種思想也很便于對整個項目進行管控。

差別:

        CommonJS是适用于伺服器端的,其中Node執行環境就是采用的CommonJS模式。它是同步加載不同子產品檔案。之是以采用同步,是因為子產品檔案都存放在伺服器的各個硬碟上,實際的加載時間就是硬碟的檔案讀取時間。

        然而AMD,Asynchronous Module Definition,即異步子產品定義。它是适用于浏覽器端的一種子產品加載方式。從名字可知,AMD采用的是異步加載方式(js中最典型的異步例子就是ajax)。浏覽器需要使用的js檔案(第一次加載,忽略緩存)都存放在伺服器端,從伺服器端加載檔案到浏覽器是受網速等各種環境因素的影響的,如果采用同步加載方式,一旦js檔案加載受阻,後續在排隊等待執行的js語句将執行出錯,會導緻頁面的‘假死’,使用者無法使用一些互動。是以在浏覽器端是無法使用CommonJS的模式的。目前,主要有兩個Javascript庫實作了AMD規範:require.js和curl.js

剛剛說到了webpack是根據commonjs書寫代碼的講講webpack

Webpack:

        webpack是一個子產品打包工具,它能把各種資源,例如JS(含JSX)、coffee、樣式(含less/sass)、圖檔等都一起打包變為靜态檔案。

        簡單說就是子產品加載器,通過使用Webpack,能夠像Node.js一樣處理依賴關系,然後解析出子產品之間的依賴,将代碼打包。

為什麼需要打包?

  • 像sass,JSX等代碼雖然極大的提高了開發效率,但是本身并不被浏覽器所識别,需要我們對其進行編譯和打包,變成浏覽器識别的代碼
  • 子產品化(讓我們可以把複雜的代碼細化為小的檔案)
  • 優化加載速度(壓縮和合并代碼來提高加載速度,壓縮可以減少檔案體積,代碼合并可以減少http請求)
  • 使用新的開發模式

webpack主要特點:

  • 以CommonJS來編寫,但也支援AMD、CMD子產品(對于新項目,推薦直接使用CommonJS);
  • 串聯式子產品加載器以及插件機制,讓其具有更好的靈活性和擴充性,例如提供對CoffeeScript、ES6的支援;
  • 可以根據配置或者智能分析打包成多個檔案,實作公共子產品或者按需加載;
  • 支援對CSS,圖檔等資源進行打包,這樣子就不用使用Grunt或Gulp(browserify隻能打包JS檔案);
  • 開發時在記憶體中完成打包,性能更快,完全可以支援開發過程的實時打包需求;
  • 對source map有很好的支援。

Source map(使調試更容易)

Source map就是一個資訊檔案,裡面儲存着位置資訊。也就是說,轉換後的代碼的每一個位置,所對應的轉換前的位置。有了它,出錯的時候,除錯工具就直接顯示原始代碼,而不是轉換後的代碼,這将給開發者帶來了很大友善。 

配置

每個項目下都必須配置有一個 webpack.config.js ,它的作用如同正常的 gulpfile.js/Gruntfile.js ,就是一個配置項,告訴 webpack 它需要做什麼。 

執行打包

如果通過npm install -g webpack方式安裝webpack的話,可以通過指令行直接執行打包指令,比如: 

$ webpack –config webpack.config.js 

這樣就會讀取目前目錄下的webpack.config.js作為配置檔案執行打包操作

常用webpack指令: 

在開發環境建構一次 

webpack 

建構并生成源代碼映射檔案 

webpack -d 

在生成環境建構,壓縮、混淆代碼,并移除無用代碼 

webpack -p 

快速增量建構,可以和其他選項一起使用 

webpack –watch 

progress 顯示打包過程中的進度,colors打包資訊帶有顔色顯示 

webpack –progress –colors

了解檔案路徑

require(‘lodash’) // 從子產品目錄查找 

require(‘./file’) // 按相對路徑查找

CSS 及圖檔的引用

require(‘./bootstrap.css’); 

require(‘./myapp.less’);

var img = document.createElement(‘img’); 

img.src = require(‘./glyph.png’);

繼續閱讀