2015-02-08 106 views
4

我正在使用MVC5/Durandal並想知道推薦的捆綁/壓縮Durandal應用程序的方法是什麼。我看到過有關使用Weyland的文檔,但將部署到Azure網站,並沒有看到如何在基於.net的部署過程中利用此功能。如何在部署到Azure時配置我的durandal應用程序的自動捆綁/縮小?捆綁和壓縮Durandal應用程序

回答

4

我花了一些時間試圖爲荷蘭最大的銀行之一優化AngularJS應用程序。雖然它不是杜蘭達爾,但這仍然會給你一些想法。

那麼我們用什麼捆綁和縮小?外的現成捆綁和minifcation從ASP.NET MVC(這是從system.web.optimization命名空間)

你需要讓一些事情,以便利用這一點:

組織您的文件

以易於捆綁的方式組織您的代碼文件。我們在Web項目的/app文件夾下有一個很大的樹形結構。喜歡的東西:

- App  
    |- Modules 
    |  |-Common 
    |  | |- Directives 
    |  | |- Templates 
    |  | |- Filters 
    |  --User 
    |   ... 
    | app.js 

所以應用程序框架是app.js內部和應用程序要求所有其他的JS文件。點是:所有SPA代碼是從供應商javscript文件分離,

設置束配置

這是一件輕而易舉的事,現在裏面的budling休息,當然,只是從你的Global.asax.cs常規舊捆綁: 確保有一列的Application_Start()有: BundleConfig.RegisterBundles(BundleTable.Bundles);

在調用你的BundleConfig類,只需要1捆收拾整個/app文件夾:

 bundles.Add(new ScriptBundle("~/bundles/app") 
      .Include("~/app/*.js") 
      .IncludeDirectory("~/app", "*.js", true)); 

我們需要首先加載app.js--因此我們明確地將它放在頂部。別擔心,它不會被要求兩次。

對於捆綁 - 只有文件序列可能很重要。但是,通過明確包含該文件,我們可以控制該文件,並像魅力一樣工作。

縮小

現在對於微小,我們不得不做一些代碼更改。 AngularJS可以用於不同類型的語法 - 其中一些可以縮小,其他則可以解決問題。

實施例:

angular.module('myapp').controller(function($http,$scope) { ... }); 

不能精縮。 minifyer將更改$http的名稱,使之更短,之後注入器不再進行依賴注入,因爲它只知道名爲$http$scope的東西,而不是縮小的變量名稱。

所以對角,你需要使用不同的語法:

angular.module('myapp').controller(['$http', '$scope', function($http,$scope) { ... }]); 

這樣,噴油器就知道該函數的第一個參數是「$ HTTP」,因爲這是數組中的第一個字符串變量。好的,但那是Angular,你正在尋找Durandal。

我聽說Durandal使用AMD的權利?所以在一個模塊中,縮小應該不成問題,因爲它應該足夠聰明。但是,如果你使用外部事物,你想確保一切仍然有效。我讀過here,你要使用TE以下語法您的AMD的:

define("someModule", ["jquery", "ko"], function($,ko) { ... }); 

這給了我們一個減少的請求的80%,對周圍的JavaScript有效載荷相同的號碼。

新增AngularJS獎金

這可能不是你的興趣,但也許其他讀者。我們沒有得到99%的請求減少的原因是因爲AngularJS使用了一些叫做'指令'的東西。這些就像HTML模板。這些HTML模板在每次使用時都需要下載。

他們也包括在我們/app文件夾 - 因此我們不得不在routeconfig添加IgnoreRoute:

routes.IgnoreRoute("app/"); 

我用Google搜索,但沒有找到任何東西similair爲迪朗達爾。所以Angular會去獲取所有的小HTML文件,但會先檢查它的$templatecache。如果HTML內容不在緩存中,則會將其下載並下載並放入緩存中,因此只需下載一次。

我們,我寫了一個T4生成器,輸出一個JS文件,其中/ app文件夾中的所有HTML文件都被添加到$templatecache。因此,輸出將類似於:

angular.module('myapp').run(function($templateCache) { 
    /// For all *.html files in the /app folder and its children 
    $templateCache.put('...filename...', '...content of html file ...'); 
}); 

因爲這個js文件是/ app文件夾裏面,它會立即獲得與應用程序捆綁在一起,無需更多的配置。這使得我們的整個應用程序的請求僅爲1.由於HTML的數量相當小,因此執行1個更大的請求,然後多個更小的請求似乎更快。要點是:如果Durandal有類似的東西,它會尋找一些模板,找到緩存機制(因爲它會有它),並試圖挖掘它。

控制捆綁和微小

我舉這個網站:http://www.asp.net/mvc/overview/performance/bundling-and-minification

捆綁和縮小時由設置在編譯元素中的調試屬性的值 啓用或禁用Web.config 文件。在以下XML中,debug設置爲true,因此捆綁和禁用縮小。

<system.web> 
    <compilation debug="true" /> 
</system.web> 

因此,對於你發佈版本 - 此標誌不應設置,從而捆綁+微小應該發生。 不過,當然,你會想在本地測試 - 你可以從你的web.config中刪除此或BundleTable.EnableOptimizations = true;

部署覆蓋它天青

然後你提到的部署到Azure上。我不知道這與部署到本地服務器有什麼不同。我們使用網絡部署。捆綁和縮小不會發生構建時間,因此構建過程中沒有任何更改。此外,優化框架正在與網站一起部署 - 因此部署也不困難。

也許有一兩件事:你可以考慮加入CDN您所使用的庫:

bundles.Add(new ScriptBundle("~/bundles/jquery", "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js") 

在案件的jQuery的CDN位置已經由客戶端的瀏覽器緩存,你可以節省另一個請求。測量性能非常簡單:只需在Chrome上打開網絡標籤並重新加載頁面(確保它不是緩存)即可。檢查請求總數和下載的數據總量。就像我說的:我們看到了巨大的進步。

那麼,希望它可以幫助或指出你在一個正確的方向。

+0

老兄,我只是再看一遍 - 這麼簡單,很好解釋。謝謝。 – RobVious 2015-03-03 04:06:34

3

下面的答案是相當複雜的。我剛剛通過這個用了一個簡單的(R)的方式在這裏:

https://lifelibertycode.wordpress.com/2015/04/14/how-to-bundle-up-your-mvc-durandal-app/

下面的步驟:

1步:安裝節點

第2步:安裝咕嘟咕嘟

$ npm install --global gulp 
$ npm install --save-dev gulp 

S TEP 3:建立gulpfile.js

這應該是在項目的根目錄,首先應包含這樣的:

var gulp = require('gulp'); 

gulp.task('default', function() { 
    // place code for your default task here 
}); 

第4步:安裝一飲而盡,迪朗達爾

npm install gulp-durandal --save-dev 

第5步:更新您的gulp文件。JS

var durandal = require('gulp-durandal'); 

gulp.task('durandal', function(){ 
    durandal({ 
      baseDir: 'app', //same as default, so not really required. 
      main: 'main.js', //same as default, so not really required. 
      output: 'main.js', //same as default, so not really required. 
      almond: true, 
      minify: true 
     }) 
     .pipe(gulp.dest('dir/to/save/the/output')); 
}); 

6步:添加一個生成後事件到項目

if '$(Configuration)'=='Release' (
    cd $(ProjectDir) 
    gulp durandal 
) 

第7步:一個預生成事件添加到您的項目

我需要這是因爲在現有版本的基礎上生成新的main-built.js時偶爾會發生吞嚥。所以,我只是刪除了舊版本的構建開始前:

if '$(Configuration)'=='Release' (
    cd $(ProjectDir)/app 
    del main-built.js 
    del main-built.js.map 
) 

現在,當你建立你的項目,你會生成一個新的主built.js每個可投放到您的客戶時文件。甜。

在這一點上,你可能有一些擔憂。

我在調試時如何保持我的文件未捆綁?

@if (HttpContext.Current.IsDebuggingEnabled) { 
     <script type="text/javascript" src="~/Scripts/require.js" data-main="/App/main"></script> 
    } else { 
     @Scripts.Render("~/Scripts/main-built") 
    } 

其中的主要建'在你的BundleConfig定義:

bundles.Add(new ScriptBundle("~/Scripts/main-built").Include(
    "~/app/main-built.js")); 

如何胸圍緩存,當我有新的東西出貨?

如果您使用上述方法,捆綁將爲您處理此問題。 ASP.NET將檢測對main-built.js文件的更改,並將唯一標識符附加到捆綁包以緩存緩存。

如果我的客戶已經下載了我的SPA,然後我發送更新,該怎麼辦? (過時的)客戶端代碼不會在刷新之前一直存在?

是。除非您利用內部版本控制來告訴客戶端何時過期,然後告訴用戶。