無論簡單或複雜的網頁應用,都由一些HTML、JavaScript、CSS檔案組成。通常開發者會透過JQuery、Knockout、Underscore等等這樣的第三方JavaScript框架來提高開發速度。由於這些JavaScript框架都針對特定的用途開發而且已經得到了“驗證”,所以直接使用它們就比自己從頭實現所需的功能顯得更為合適。然而,伴隨著應用的複雜度不斷上升,寫出乾淨、低耦合、可維護的程式碼變得越來越重要。在這篇文章裡,我將解釋 RequireJS框架如何幫助應用程式開發者寫出更模組化的程式碼,以及它是如何透過延遲載入JavaScript檔案來提高應用程式效能的。
開始的部分我們先不用RequireJS框架,然後在下一個章節用RequireJS來重構它。
下面的這個HTML頁麵包含了一個id為「message」的
元素。當使用者造訪這個頁面的時候,它將展示訂單Id和客戶姓名資訊。
Common.JS檔案包含了兩個模組的定義-Order和Customer。函數showData和頁面的body結合在一起,它透過呼叫write函數來把要輸出的資訊放入頁面中。作為範例,我在showData函數裡硬編碼了Id為1,客戶姓名為Prasad。
<!DOCTYPE html> <html> <head> <title>JavaScript NonRequireJS</title> <script src="common.js" type="text/javascript"></script> </head> <body> <strong>Display data without RequireJS</strong> <p id="message" /> <script type="text/javascript"> showData(); </script> </body> </html> Common.JS function write(message) { document.getElementById('message').innerHTML += message + '</br>'; } function showData() { var o = new Order(1, "Prasad"); write("Order Id : " + o.id + " Customer Name : " + o.customer.name); } function Customer(name) { this.name = name; return this; } function Order(id, customerName) { this.id = id; this.customer = new Customer(customerName); return this; }
在瀏覽器中開啟這個頁面,你將會看到如下的資訊。
雖然上面的程式碼能夠顯示輸出,但是它仍有一些問題:
RequireJS框架處理了JavaScript檔案間的依賴關係,並且根據需要按順序載入它們。
用RequireJS搭建應用程式
現在讓我們來看看重構過的程式碼。下面的HTML程式碼引用了Require.JS檔。 data-main屬性定義了這個頁面的唯一入口點。在下面這個場景中,它告訴了RequireJS在啟動的時候載入Main.js。
<!DOCTYPE html> <html> <head> <title>JavaScript RequireJS</title> <script src="Require.Js" type="text/javascript" data-main="Main.js"></script> </head> <body> <strong>Display data using RequireJS</strong> <p id="message" /> </body> </html>
Main.JS
由於這個檔案已經透過data-main屬性指定,RequireJS將會盡快的載入它。這個檔案使用了RequireJS框架的函數來決定和定義對於其它JavaScript檔案的依賴關係。在下面的程式碼片段裡,第一個參數表示依賴關係(依賴Order.JS檔),第二個參數為一個回調函數。 RequireJS分析所有的依賴關係並載入它們,然後執行這個回呼函數。請注意,第一個參數的值(Order)必須和檔案名稱一致(Order.JS)。
require(["Order"], function (Order) { var o = new Order(1, "Prasad"); write(o.id + o.customer.name); });
Order.JS
RequireJS框架提供了一個定義和維護JavaScript檔案間依賴關係的簡單途徑。下面程式碼中的define函數宣告了Customer.JS必須在處理Order回呼函數前載入。
define(["Customer"], function (Customer) { function Order(id, custName) { this.id = id; this.customer = new Customer(custName); } return Order; } ); Customer.JS
這個文件不依賴任何其它JavaScript文件,所以define函數的第一個參數的值是一個空數組。
define([], function () { function Customer(name) { this.name = name; } return Customer; } );
好了,現在用你的瀏覽器打開這個應用,你將會看到如下的輸出。要注意的是RequireJS只載入了必要的JavaScript檔案。
總結
在這篇文章裡,我們分析了RequireJS框架是如何處理JavaScript檔案間的依賴關係並根據需要載入它們的。它能夠幫助開發者寫出更鬆散耦合、更模組化且更具可維護性的程式碼。