我正在使用MVC5 / Durandal,并想知道捆绑/缩小durandal应用程序的推荐方法是什么。我见过有关使用Weyland的文档,但是将部署到Azure网站,并且没有看到如何在基于.net的部署过程中利用它。在部署到Azure时,如何配置我的durandal应用程序的自动捆绑/缩小?
答案 0 :(得分:4)
我花了一些时间试图为荷兰最大的银行之一优化AngularJS应用程序。虽然它不是Durandal,但这可能仍会给你一些想法。
那么我们用什么来捆绑和缩小? ASP.NET MVC(来自system.web.optimization
命名空间)的开箱即用的捆绑和分割
为了利用这一点,你需要做一些事情:
整理文件
以易于捆绑的方式整理代码文件。我们在Web项目的/app
文件夹下有一个大型树结构。类似的东西:
- App
|- Modules
| |-Common
| | |- Directives
| | |- Templates
| | |- Filters
| --User
| ...
| app.js
因此应用程序框架位于app.js
内,并且应用程序需要所有其他JS文件。要点:所有SPA代码都与供应商javscript文件分开,其余当然是
在捆绑配置中设置萌芽
现在这很简单,只需从你的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,您需要使用不同的语法:
angular.module('myapp').controller(['$http', '$scope', function($http,$scope) { ... }]);
这样,注入器就会知道函数的第一个参数是&#39; $ http&#39;因为那是数组中的第一个字符串变量。好的,但是那个Angular,你正在寻找Durandal。
我听说Durandal使用AMD吗?因此,在一个模块中,缩小不应该是一个问题,因为它应该足够聪明。但是,如果您正在使用外部事物,则需要确保一切仍然有效。我已阅读here您希望为您的AMD使用以下语法:
define("someModule", ["jquery", "ko"], function($,ko) { ... });
这使我们减少了80%的请求,并且Javascript负载的数量大致相同。
添加了AngularJS奖金
这可能不是您感兴趣的,但可能对其他读者感兴趣。我们没有将请求减少99%的原因是因为AngularJS使用了一些名为&#39;指令&#39;。这些就像HTML模板。每次使用时都需要下载这些HTML模板。
它们也包含在我们的/app
文件夹中 - 因此我们必须在routeconfig中添加一个IgnoreRoute:
routes.IgnoreRoute("app/");
我用Google搜索,但无法找到Durandal的任何类似内容。因此,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中编译元素中的debug属性的说明 文件。在以下XML中,debug设置为true,因此捆绑和 缩小是禁用的。
<system.web>
<compilation debug="true" />
</system.web>
因此,对于您的发布版本 - 不应该设置此标志,因此捆绑+缩小应该发生。
但是,当然,您需要在本地进行测试 - 您可以从web.config中删除它,也可以使用BundleTable.EnableOptimizations = true;
覆盖它
部署到Azure
然后提到Azure的部署。我不知道这与部署到本地服务器有什么不同。我们使用了web-deploy。捆绑和缩小不会在构建时发生,因此构建过程中没有任何变化。此外,优化框架正在与站点一起部署 - 因此也没有困难的部署。
也许有一件事:您可以考虑为您正在使用的库添加CDN:
bundles.Add(new ScriptBundle("~/bundles/jquery", "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js")
如果客户端的浏览器已经缓存了jQuery的CDN位置,您将保存另一个请求。
衡量效果很简单:只需打开Chrome上的网络标签页并重新加载页面(确保它没有缓存)。检查请求总数和下载的数据总量。就像我说的那样:我们看到了巨大的进步。
嗯,希望它有助于或指出你正确的方向。
答案 1 :(得分:3)
以下答案非常复杂。我在这里通过简单的(r)方法完成了这个过程:
https://lifelibertycode.wordpress.com/2015/04/14/how-to-bundle-up-your-mvc-durandal-app/
以下步骤:
第1步:安装节点
第2步:安装Gulp
$ npm install --global gulp
$ npm install --save-dev gulp
第3步:创建gulpfile.js
这应该是项目的根目录,最初应该包含:
var gulp = require('gulp');
gulp.task('default', function() {
// place code for your default task here
});
第4步:安装gulp-durandal
npm install gulp-durandal --save-dev
第5步:更新您的gulpfile.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时,偶尔会挂掉gulp。所以我只是在构建开始之前删除旧版本:
if '$(Configuration)'=='Release' (
cd $(ProjectDir)/app
del main-built.js
del main-built.js.map
)
现在,当您构建项目时,每次可以向您的客户提供服务时,您将生成一个新的main-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中定义'main-built':
bundles.Add(new ScriptBundle("~/Scripts/main-built").Include(
"~/app/main-built.js"));
当我有新东西要发货时,如何暂停缓存?
如果您使用上述方法,捆绑将为您解决此问题。 ASP.NET将检测对main-built.js文件的更改,并为您的包附加一个唯一标识符以破坏缓存。
如果我的客户下载了我的SPA,然后我发送了更新,该怎么办? (过时的)客户端代码是否会在刷新之前保持不变?
烨。除非您利用构建版本控制来告诉客户端何时过时,然后告诉用户。
答案 2 :(得分:0)