1. 程式人生 > >JS模組化程式設計總結

JS模組化程式設計總結

一、背景

隨著的網際網路技術的不斷髮展,瀏覽器逐漸成了集大成的CS客戶端,頁面功能在向系統級、軟體級靠攏的趨勢下,開發團隊也需要一些軟體工程的方法來開發WEB專案,如測試驅動、面向物件,而模組化程式設計更是成為一種急需應用的技術。

二、原因

為方便檔案管理、增加複用,我們需要細化JS檔案,每個檔案負責單一職能,稱之為模組,明確每個檔案的職能,當互動功能較複雜時,引用的檔案也越加龐大,此時我們就需要模組化管理。

如我們編寫一個模組元件Dialog.js,其依賴event.js / bootstrap.js / component.js,而event.js又依賴 base.js / core.js / el.js,bootstrap.js依賴 boot.js / under.js / almond.js,同理可能依賴更多的js,傳統方法我們用到Dialog.js時實際上需要引用9個js,如下

<html>
<body>
...
 <script src="/public/base.js"></script>
 <script src="/public/core.js"></script>
 <script src="/public/el.js"></script>
 <script src="/public/boot.js"></script>
 <script src="/public/under.js"></script>
 <script src="/public/almond.js"
>
</script> <script src="/module/event.js"></script> <script src="/module/bootstrap.js"></script> <script src="/module/component.js"></script> <script src="/widget/dialog.js"></script> </body> </html>

我們將其細分,Dialog所依賴的每個js都負責了某一獨立功能,分開便於其它元件複用,也利於學習理解。

但將這9個js都到html裡顯示引用,工作量卻非常可觀,且不能弄錯路徑及載入順序,若後續Dialog.js又需要多引用一個js,所有的專案都要手動增加,且這樣依次同步載入下來會導致會佔用瀏覽器執行緒,可能導致假死。

三、作用

模組化的作用就是解決上面提到的兩點問題。

1、實現js檔案的非同步載入,避免瀏覽器假死。
2、管理模組之間的依賴,便於模組的維護

四、實現

模組化,就是把一個相對獨立的功能,單獨成一個檔案,可輸入指定依賴、輸出指定的函式,供外界呼叫,其它都是內部的。這樣即可方便不同的專案重複使用,也不會對其造成額外的影響。而既然要給不同的專案應用,特別像git上的模組是面向全球範圍的,必然要形成可遵循的規範,開發者和使用者都有據可尋。

目前通用javascript規範分為服務端(CommonJS),客戶端(AMD / CMD)。

CommonJS是針對javascript的服務端,一切模組都是通過require來同步載入呼叫, Nodejs採用的就是這個規範。

var module1 = require( 'module1'),
      module2 = require( 'module2' );

function module3(){
     ...
 }
exports.module3 = module3;

注:通過require載入module1、2,操作後通過exports導致module3。

這裡我們主要講客戶端模組

客戶端與服務端的不同在於非同步載入,之所以非同步是因為CommonJS規則應用在服務端時,檔案都是本地硬碟讀取,不受限於網路,等待硬碟讀取時間很短。而瀏覽器要考慮網速,若長時間等待會導致瀏覽器假死。

引用形式如下圖

五、AMD

是"Asynchronous Module Definition"的縮寫,意思就是"非同步模組定義",

=============main.js===================
 <script src="js/require.js" data-main="js/Dialog"></script>

==============Dialog.js=======================
 define( ['event', 'bootstrap', 'component' ], function( event, bootstrap, component ){
      event.doSomthing();
      bootstrap.doSomthing();
       component.doSomthing();
      var Dialog = function(){
          ...
      }
      return {
          Dialog: Dialog
     }
 });

注:require接收兩個引數,第一個引數是陣列,含需載入的模組,第二個引數是回撥,在模組載入成功後執行,且回撥中的引數對應模組的載入順序,這樣主程式只需要載入一個JS檔案,Dialog.js即可,其自會去載入event.js等檔案,event.js再用同樣的方式去載入base.js等,使用者無需考慮Dialog載入了多少引用,也無法擔心其使用後會增減依賴。

六、CMD

 =============main.js===================
 <script src="js/sea.js"></script>    
<script>seajs.use("../static/hello/src/main")</script>

==============Dialog.js=======================
define( function( require, exports, module ){
    var event = require( 'event' );
    event.doSomthing();
    var bootstrap = require( 'bootstrap' );
    bootstrap.doSomthing();
    var component = require( 'component' );
    component.doSomthing();
    var Dialog = function(){
         ...
    }                    
     exports.Dialog = Dialog;
})

注:模組引用本身就在回撥裡,並且在使用前引用即可,所以sea.js強調的是懶載入,這也就是AMD和CMD之間唯一的區別。實際上,require.js也支援CMD的寫法,不過依賴前置是其官方推薦。我最初因為對國產和玉伯的支援敬佩,使用了seajs,近來為了弄清楚AMD,專案全部用了requirejs,雖然網上及seajs官方對兩種邏列了一些分別,但使用下來,感覺並無優劣。

七、UMD

因服務端與客戶端對模組化載入方式的不同,就會人想做一個相容的模組UMD(Universal Module Definition),來解決跨平臺的問題。但對於我們開發者來講實則沒有什麼意義,也不深入了。

八、require.js 使用

require.config({
      baseUrl: 'module/js',     //配置path下的統一目的,以便path中不會分別配置
      path: {                              //配置module路徑,以便引用時不用寫全路徑
          module1: 'module1',
          module2: 'module2',
          module3: 'http://www.site.com/module3'     //若引用的是第三方,可以全部全路徑
     },
      shim: {     //對不符合AMD規則的模組引用
          'underscore': {
               exports: '_'          //配置其原對外介面
          },
          'backbone': {
               deps: ['underscore', 'jquery'],     //配置其依賴項
               exports: 'Backbone'
         }
     }
 });

define( ['module1', 'module2' ], function( module1, module2 ){
      module1.doSomthing();
      module2.doSomthing();
      function module3(){
          ...
     }
      return {
          module3: module3
     }
 })

九、require.js 時間戳

require.js沒有找到可配置時間戳,可修改require.js原始檔中的load方法

 load: function (id, url) {
    url += '?' + timestamp;     
    req.load(context, id, url);     
},

新增 url += '?' + timestamp; 這一處語句,即為url新增timestamp,timestamp可以另外通過配置檔案配置。我使用nodejs開發,在服務端的config檔案配置 timestamp: '2015091112',將其插入到客戶端 ejs檔案內

 <script>
     var timestamp = '<%= timestamp %>';
 </script>

這樣即可在 require.js 檔案內呼叫。

十、require.js 合併

官網提供了r.js用於該模組化的打包 https://github.com/jrburke/r.js
r.js是將通過require.js引用的模組化檔案都合併到一個檔案裡,以減少檔案載入數量。
專案參考 https://github.com/xiaolulu/mynodejs.git| d7a0f54705a10ac329dd2f62a7d569da2 |
首先下載r.js,可以到靜態檔案根目錄,新建build.js用於配置r.js,常見的配置如下


build.js

({ 
    appDir: './', //專案根目錄,給後面的baseUrl做參考;非必要項;預設為與r.js平級目錄
    dir: './min', //壓縮後的檔案的輸出目錄 
    baseUrl: './', //模組相對目錄,與後面的paths配置使用
    modules: [ 
            { name:'login'},
            { name: 'register' },
            { name: 'center' }
    ], 
    fileExclusionRegExp: /^(r|build)\.js|.*\.scss$/, //過濾檔案不壓縮
    optimizeCss: 'standard', //css的標準方式
    optimize: 'uglify', //設定是否壓縮;uglify(壓縮格式)|none(只合並不壓縮)
    removeCombined: true, //設定移除壓縮後的檔案
    paths: { //設定模組別名,方便引用,壓縮後require.js引用的模組路徑就在這裡定義的,不是require.config裡的
            md5: 'core/js/md5',
            validate: 'widget/validate/validate',
            all: 'public/js/all',
            login: 'module/issue/login/login',
            register: 'module/issue/register/register',
            center: 'module/user/center/center'
    }
})

shell執行 node r.js -o build.js

十一、almond

合併後所有原通過模組化載入的檔案都已經在一個檔案裡了,已經不需要require.js的大部分功能,但因合併後代碼裡還是有require / define的函式定義,這裡命令解析還是要有的,所以就有了almond.js(約15KB),其保留了require.js(約80KB)的子集,但不支援模組化載入,即對已經合併後的模組解析可以使用,減少程式碼量。

不過,其理念是好的,但實現方案還待改進,其執行後就會almond.js與前面合併後過的業務JS合併成一個檔案,直接用 src來引用,意味著每個頁面都需要的 almond.js將無法快取,所以當業務JS超過五個時,這個方案將沒有意義,有興趣可以自行到git上學習,這裡不在講述 https://github.com/jrburke/almond

轉載:https://segmentfault.com/a/1190000003780523

相關推薦

JS模組程式設計總結

一、背景 隨著的網際網路技術的不斷髮展,瀏覽器逐漸成了集大成的CS客戶端,頁面功能在向系統級、軟體級靠攏的趨勢下,開發團隊也需要一些軟體工程的方法來開發WEB專案,如測試驅動、面向物件,而模組化程式設計更是成為一種急需應用的技術。 二、原因 為方便檔案管理、增加複用

js-模組開發總結

一.模組開發的概念 模組化開發是什麼:模組化開發是一種生產方式,這種方式生產效率高,維護成本低。從軟體開發的角度說,模組化開發是一種開發模式,寫程式碼的一種方式,開發效率高,維護成本低。 為什麼需要模組化開發:當一個專案開發的越來越複雜的時候,會遇到一些問題,比如命名衝突(重新命名),檔

JS模組程式設計之AMD模型實現原理(Requirejs瀏覽器模型,nodejs伺服器模型)

官方引數手冊:https://requirejs.org/docs/api.html     /** * require使用指南! * 第一步:建立一個符合Require CMD模組化的標準目錄結構,去官方檢視! * 第二步:在html檔案中指定主js檔

JS模組程式設計之AMD規範(一)

隨著網站逐漸變成"網際網路應用程式",嵌入網頁的Javascript程式碼越來越龐大,越來越複雜。 網頁越來越像桌面程式,需要一個團隊分工協作、進度管理、單元測試等等......開發者不得不使用軟體工程的方法,管理網頁的業務邏輯。 JavaScript模組化程式設

js模組總結

從前端打包的歷史談起   在很長的一段前端歷史裡,是不存在打包這個說法的。那個時候頁面基本是純靜態的或者服務端輸出的, 沒有 AJAX,也沒有 jQuery。Google 推出 Gmail 的時候(2004 年),XMLHttpRequest, 也就是我們俗稱的 AJAX被拾起的時候,前端開發者開

js模組程式設計之徹底弄懂CommonJS和AMD/CMD!

先回答我:為什麼模組很重要?   答:因為有了模組,我們就可以更方便地使用別人的程式碼,想要什麼功能,就載入什麼模組。但是,這樣做有一個前提,那就是大家必須以同樣的方式編寫模組,否則你有你的寫法,我有我的寫法,豈不是亂了套! 於是下面三個模組規範出來了,這篇文章也出來了(拼出來的 {捂臉笑})。 &

點選按鈕刪除bootstrapTable選中行,js模組及一些問題的總結

頁面效果展示 html程式碼: <div class="col-md-12" style="height: 15%"> <form action="web?module=stwmgr&action=Develop&method=se

Javascript模組程式設計之路——(require.js)

轉自:http://www.ruanyifeng.com/blog/2012/10/javascript_module.html Javascript模組化程式設計(一):模組的寫法 隨著網站逐漸變成"網際網路應用程式",嵌入網頁的Javascript程式碼越來越龐大,越來越複雜。 網頁越來越像桌面程式

prism模組問題總結(1)

在prism模組化時,IRegion提供了新增View和Remove的方法.下面對一些會遇到的問題進行討論。 以下為Demo的Shell,一個Menu的Region,兩個內容區域. <StackPanel> <Menu cal:RegionManager.RegionNam

prism模組問題總結(2)

繼續討論出現的問題   1.重新載入時,不要將view臨時儲存起來 理由:這樣將導致重新載入時,view的容器還存在,view無法加入。還會導致記憶體的問題.刪除時也應該將其刪除. 如 private List<object> viewList = new

JS模組(Module模式模組,SeaJS工具模組)

1、Module模式模組化 Module模式具有模組化,可重用的基本特徵,封裝了變數和function,只暴露可用public的方法,其它私有方法全部隱藏。在沒有使用模組化工具的情況下,用模組化的思想來編寫整個JS結構。 例如下圖,以webrtcUI層程式碼為例,MeetingMainPag

JavaScript模組程式設計之AMD

簡單的說一下AMD是"Asynchronous Module Definition"的縮寫,意思就是"非同步模組定義"。它採用非同步方式載入模組,模組的載入不影響它後面語句的執行。所有依賴這個模組的語句,都定義在一個回撥函式中,等到載入完成之後,這個回撥函式才會執行。 require.js作用

require-js-模組 CMD AMD

模組化的標準有了模組,我們就可以更方便地使用別人的程式碼,想要什麼功能,就載入什麼模組。這樣做有一個前提,那就是大家必須以同樣的方式編寫模組,否則你有你的寫法,我有我的寫法,豈不是亂了套!  CommonJS:是一個模組化的標準,Node.js在使用的模組化標準。適用與後端開發的標準。AMD(As

node,npm,webpack,vue-cli模組程式設計安裝流程

首先什麼都不要管,先裝環境。 pip是萬能的!!! 安裝node:  pip3 install node 安裝npm:   pip3 install npm 安裝webpack:  npm install webpack 安裝vue-cli:  npm install vue-

JS模組(一):CommonJS

模組化的規範:         目前有四種:             1.CommonJS      &nbs

模組程式設計——小甲魚

把程式劃分成多個組成部分,即所謂的“模組”。 這是通過把程式程式碼分散到多個檔案裡,等編譯程式時再把那些檔案重新組合在一起實現的。 標頭檔案的基本用途是提供必要的函式宣告和類宣告。 系統標頭檔案的另一個重要作用是保證c++程式碼的可移植性,確保同樣的c++程式碼在不同的作業系統上做同樣的事情。 可以用

C程式設計|用函式實現模組程式設計詳解(一)

目錄 一、為什麼要用函式 使用函式可使程式清晰、精煉、簡單、靈活。 函式就是功能。每一個函式用來實現一個特定的功能。函式名應反映其代表的功能。 在設計

node.js模組思想初探

系統模組(核心模組):node本身自帶,可以直接require的模組 自定義模組:自己寫的,以及在npm上下載的模組 一部分常用的系統模組的作用(印象) Crypto 加密 Events 事件 Net 網路操作 OS 作業系統資訊 Path 處理檔案路徑 S

【requirejs】JS模組工具requirejs教程

初識requirejs 隨著網站功能逐漸豐富,網頁中的js也變得越來越複雜和臃腫,原有通過script標籤來匯入一個個的js檔案這種方式已經不能滿足現在網際網路開發模式,我們需要團隊協作、模組複用、單元測試等等一系列複雜的需求。 RequireJS是一個非常小巧的JavaScript模組載入框架,是A

JS模組開發規範

JS模組化開發規範,以下介紹三種 commonJS規範(Nodejs模組系統遵循此規範,適用於服務端) 1、 規範定義 CommonJS規範規定,一個檔案就是一個模組,用module變數代表當前模組。 Node在其內部提供一個Module的構建函式。所有模組都是Module的例項 2、 module.ex