js模塊化開發---js大項目代碼組織和多人協作的解決之道


Js開發在整個行業的現狀主要的有兩點

ž 維護成本高
ž多人協作項目的困境
 
Js項目維護成本過高
 
經歷過10年的ie統治時期的瀏覽器世界一成不變,和06年開始ajax的興起帶動垂死的javascript的復興,瀏覽器市場也開始翻天覆地的快速變化,排版引擎和js腳本引擎開始得到不斷的優化,js的執行效率不斷的得到提高,但是………..
 
我們的js一直沒變過. 現在所有的主流 Web 瀏覽器都遵守 ECMA-262 第三版,即實現的是JavaScript 1.5版  時間 2000
 
ž那么,js依然是當年的js,瀏覽器和對web的需求早已經不復當年。當年那個為做表單驗證而生的js語言,如今承擔的是復雜的界面ui和交互處理,以前只需要寫十幾行或者幾十行的js現在需要面對幾千上w行的需求。
 
ž那么帶來的問題就是十年來js語言特有的隨意性導致的各路js程序員的js風格各異。
 
žJs的弱類型特性導致項目中經常會出現jser的各種奇技淫巧。
 
ž上面的兩問題直接導致的是js程序交接維護上的困難。面對js風格清晰易懂的jser的代碼還好,如果接手js風格怪異太個性的jser的代碼,並且如果還沒有注釋,那么,看代碼真心會看到你吐血
 
編寫規范的隨意性 ,編寫風格的個性化,是js項目維護成本的很大一部分原因
 
多人協作項目的困境
ž其實看過前面的內容,我們大抵的了解到,js是應很簡單的需求而生的,甚至簡單到是用來做簡單的表單驗證的。也就是說,js代碼,在很長一段時間內,都是由一個開發獨立完成的,多人協作上會出現的問題

1,全局變量命名混亂沖突導致系統錯誤

2,代碼集中少量文件導致開發效率降低

3,容易出現功能重復開發

Js開發編寫方式的演進

ž函數 – js作為函數式語言與生帶來的特性,jser們通過在window下注冊一個又一個的function相互調用來完成產品們的需求(全局變量命名極為混亂和不規范)
 
ž ---jser為大型js項目開發的嘗試, 2006年, Ajax 興起。JavaScript絕地重生,越來越多的后端邏輯放到了前端。網頁中的JS代碼量急劇增加。這時寫函數方式組織大量代碼顯得力不從心。有時調試一個小功能,從一個函數可能會跳到第N個函數去。這時jser們前仆后繼,進行各樣嘗試,類出現了, Prototype 率先流行開來。用它組織代碼,用js的靈活性模擬類的編程,每個類都是Class.create創建的。又有 YUIExt等重量級框架。雖然它們的 創建 類方式各不同,但它們的設計終極目標卻都是要滿足大量JavaScript代碼的開發而努力
ž類開發嘗試的轉折-------這是一個戰火紛飛的年帶,各路框架豪傑不斷涌現,jq的誕生帶來了js開發的又一次變革,jq所至,其他框架寸草不生,同時也直接導致 prototype 等“類”的嘗試又化為烏有,很大一幫jser轉投jq尤其是js新手直接着手jq者,在享受了jq在小型頁面dom操作的遍歷之后,大型js項目的多人協作和代碼組織問題又暴露到了台前,甚至是制約js乃至整個web發展的一個不小的因素
 
那么,模塊化開發——現在,未來?
žCommonjs,首先要說下這個。何為commonJS?commonJs可以理解成一個組織,他們中的所有人都致力於提高javascript程序的可移植性以及可交互性。在js模塊化開發上做各種的嘗試,這種可移植性以及可交互性不僅僅局限於瀏覽器端,而且也包括了服務器端的javascript, CommonJS 提出了一種用於同步或異步動態加載JavaScript代碼的API規范,非常簡單卻很優雅,稱之為 AMD(Modules / Asynchron , RequireJS和NodeJS的 Nodules已經實現了這個API,而Dojo也將馬上完全支持(Dojo1.6)。規范本身非常簡單,甚至只包含了一個API:
ždefine([module-name?], [array-of-dependencies?], [module-factory-or-object]);
 
ž這個就是差不多的整個amd規范的定義。我們這里主要已requirejs為例做個簡單的說明
 
 
RequireJS快速入門-模塊定義
 
ž定義的是一個簡單的鍵值對數據模塊ž

//Inside file my/shirt.js:

 define({

    color: "black",

    size: "unisize“

 });

 

Definition Functions

ž定義的模塊包裝在一個function內 

define(function () {

//Do setup work here

    return {

       color: "black",

       size: "unisize“

 }

 });

 

Definition Functions with Dependencies

ž定義一個有模塊依賴關系的模塊

//module in the same directory as shirt.js

define(["./cart", "./inventory"], function(cart, inventory) {

        //return an object to define the "my/shirt" module.

        return {

             color: "blue",

             size: "large",

             addToCart: function() {

                 inventory.decrement(this);

                 cart.add(this);

             }

        }

} );

那么,執行了這個模塊的初始化會依次的加載順序為

my/cart.js

my/inventory.js

my/shirt.js

 

Define a Module as a Function

ž定義的模塊為返回一個function

define(["my/cart", "my/inventory"], function(cart, inventory) {

    //return a function to define "foo/title".

   //It gets or sets the window title.

   return function(title) {

      return title ? (window.title = title) : inventory.storeName + ' ' + cart.name;

   }

} );

 

Define a Module with Simplified CommonJS Wrapper

ž定義一個簡單的commonjs包裝

define(function(require, exports, module) {

       var a = require('a'),

             b = require('b');

//Return the module value

       return function () {};

 } );

 

這個定義就可以把模塊內部的任何變量暴露給exports來作為模塊的屬性提供。比如:

內有個定義

 var name=‘nickli’;

這個就僅僅是模塊的內部私有變量,但是要想作為這個模塊的屬性提供就可以

Exports.name=“nickli”; 

然后在require這個模塊的時候 就可以訪問到name這個屬性了

 

最后一點,也是比較重要的一點

Define a Module with a Name  給一個模塊設置一個名字,這個在多個模塊壓縮成一個文件的時候是必要的,因為否則模塊系統就找不到你壓縮的文件里面哪個模塊是哪個。而且這個name的定義 在你的開發環境中也要符合模塊文件的路徑,比如你的m模塊在a文件夾下,那么你的name 的定義也要是 a/m 

//Explicitly defines the "foo/title" module:
define("foo/title", ["my/cart", "my/inventory"], function(cart, inventory) { //Define foo/title object in here. } );

 

模塊化后的加載

 

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

Require.js加載完畢后會自動去 拉取scripts/main.js

ž

//Inside scripts/main.js

žrequire(["some/module", "a.js", "b.js"], function(someModule) { //... });

會依次加載some/module.js   a.js b.js三個文件

 

模塊化后的新問題

ž目前nodejs的模塊系統是嚴格遵循的commonjs  規范實施的,但是要注意到,nodejs是運行在server端的,然而瀏覽器端編程和server的最大不同是server的所有模塊文件都是在server和主文件是一塊的。而瀏覽器要面對的是大量的模塊文件帶來的大量http請求的問題, 嗯, 這個問題在瀏覽器端是致命的。。。。。。。
 
 

 

ž不過我們有 combo   動態文件壓縮技術,這里不詳述,前面已經有一隨筆 講述 require來實現combo的支持
 
關於js的模塊化開發和amd相關資料,在 http://www.cnblogs.com/snandy/里有不少更加詳細的資料。

 

 

 


 
 

 



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM