捆绑和缩小(BundleConfig.RegisterBundles) 第五章 : MVC中的使用

来源:互联网 发布:ms sql server 编辑:程序博客网 时间:2024/05/06 09:41


使用捆绑与 ASP.NET MVC 放缩法

在这一节我们将创建 ASP.NET MVC 项目,审查捆绑和缩小。首先,创建一个新的 ASP.NET MVC 互联网项目,命名为MvcBM ,而无需更改任何默认设置。

打开App_Start\BundleConfig.cs文件并检查的 RegisterBundles方法,用于创建、 注册和配置包。下面的代码演示RegisterBundles方法的部分。

 public static void RegisterBundles(BundleCollection bundles){     bundles.Add(new ScriptBundle("~/bundles/jquery").Include(                 "~/Scripts/jquery-{version}.js"));         // Code removed for clarity.}

上面的代码中创建名为~/bundles/jquery,其中包括所有适当的新 JavaScript 束 (这是调试或模糊不清但不是。vsdoc) 在脚本文件夹中的文件相匹配的通配符字符串"~/Scripts/jquery-{版本}.js"。对于 ASP.NET MVC 4,这意味着调试配置中,文件jquery 1.7.1.js将被添加到包。在发布配置, jquery 1.7.1.min.js将被添加。捆绑框架如以下几个共同的约定:

  • 如果“FileX.min.js”和“FileX.js”都存在,请为发行版选择“.min”文件。
  • 选择用于调试的非".min"版本。
  • 忽略"-vsdoc"仅使用智能感知的文件 (如 jquery-1.7.1-vsdoc.js)。

如上所示的{version}通配符匹配用于自动创建一个 jQuery 束具有适当版本的 jQuery脚本文件夹中。在此示例中,使用通配符提供了以下好处:

  • 允许您使用 NuGet 更新到新的 jQuery 版本而无需更改前面的绑定代码或 jQuery 引用在您查看网页。
  • 自动选择完整版,为调试配置和发布的".min"版本生成。

使用 CDN

以下代码将使用 CDN jQuery 绑定来替换本地 jQuery 绑定。
public static void RegisterBundles(BundleCollection bundles){    //bundles.Add(new ScriptBundle("~/bundles/jquery").Include(    //            "~/Scripts/jquery-{version}.js"));    bundles.UseCdn = true;   //enable CDN support    //add link to jquery on the CDN    var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";    bundles.Add(new ScriptBundle("~/bundles/jquery",                jqueryCdnPath).Include(                "~/Scripts/jquery-{version}.js"));    // Code removed for clarity.}

在上面的代码中,jQuery 将请求从 CDN 虽然在释放模式和 jQuery 的调试版本将被回迁本地在调试模式下。当使用 CDN,你应该有一个回退机制在 CDN 请求失败的情况下。下面的标记片段从布局文件的末尾显示脚本添加请求 jQuery 应 CDN 失败。

        </footer>        @Scripts.Render("~/bundles/jquery")        <script type="text/javascript">            if (typeof jQuery == 'undefined') {                var e = document.createElement('script');                e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")';                e.type = 'text/javascript';                document.getElementsByTagName("head")[0].appendChild(e);            }        </script>         @RenderSection("scripts", required: false)    </body></html>

创建包

包类Include方法需要的字符串数组,其中每个字符串是资源的虚拟路径。下面的代码从App_Start\BundleConfig.cs文件的 RegisterBundles 方法显示出多个文件添加到包:

bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(          "~/Content/themes/base/jquery.ui.core.css",          "~/Content/themes/base/jquery.ui.resizable.css",          "~/Content/themes/base/jquery.ui.selectable.css",          "~/Content/themes/base/jquery.ui.accordion.css",          "~/Content/themes/base/jquery.ui.autocomplete.css",          "~/Content/themes/base/jquery.ui.button.css",          "~/Content/themes/base/jquery.ui.dialog.css",          "~/Content/themes/base/jquery.ui.slider.css",          "~/Content/themes/base/jquery.ui.tabs.css",          "~/Content/themes/base/jquery.ui.datepicker.css",          "~/Content/themes/base/jquery.ui.progressbar.css",          "~/Content/themes/base/jquery.ui.theme.css"));

捆绑类IncludeDirectory方法被提供要添加一个目录 (和 (可选) 的所有子目录) 中与搜索模式匹配的所有文件。包类IncludeDirectoryAPI 如下所示:

 public Bundle IncludeDirectory(     string directoryVirtualPath,  // The Virtual Path for the directory.     string searchPattern)         // The search pattern.  public Bundle IncludeDirectory(     string directoryVirtualPath,  // The Virtual Path for the directory.     string searchPattern,         // The search pattern.     bool searchSubdirectories)    // true to search subdirectories.

在视图中使用 Render 方法中,(对 CSS Styles.Render ) 和Scripts.Render的 JavaScript 来引用的捆绑包。Views\Shared\_Layout.cshtml文件下面的标记显示默认 ASP.NET 互联网项目视图如何引用 CSS 和 JavaScript 的捆绑包。

<!DOCTYPE html><html lang="en"><head>    @* Markup removed for clarity.*@        @Styles.Render("~/Content/themes/base/css", "~/Content/css")    @Scripts.Render("~/bundles/modernizr")</head><body>    @* Markup removed for clarity.*@      @Scripts.Render("~/bundles/jquery")   @RenderSection("scripts", required: false)</body></html>

请注意渲染方法采用字符串数组,因此您可以在一行代码中添加多个软件包。你一般会想要使用所创建的必要的 HTML 来引用该资产的渲染方法。您可以使用 Url方法生成的 URL,该资产,而引用该资产所需的标记。假设你想要使用新的 HTML5async属性。下面的代码演示如何引用 modernizr 使用Url的方法。

<head>    @*Markup removed for clarity*@    <meta charset="utf-8" />    <title>@ViewBag.Title - MVC 4 B/M</title>    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />    <meta name="viewport" content="width=device-width" />    @Styles.Render("~/Content/css")   @* @Scripts.Render("~/bundles/modernizr")*@    <script src='@Scripts.Url("~/bundles/modernizr")' async> </script></head>

使用"*"通配符字符,请选择文件

Include 方法和IncludeDirectory 方法中的搜索模式中指定的虚拟路径可以接受一个"*"通配符字符作为前缀或后缀来中最后一个路径段。搜索字符串是区分大小写。IncludeDirectory方法有选择搜索子目录。

与下面的 JavaScript 文件考虑一个项目:

  • Scripts\Common\AddAltToImg.js
  • Scripts\Common\ToggleDiv.js
  • Scripts\Common\ToggleImg.js
  • Scripts\Common\Sub1\ToggleLinks.js

dir imag

下表显示的文件添加到捆绑使用通配符,如图所示:

电话添加文件或引发异常Include("~/Scripts/Common/*.js")AddAltToImg.js,ToggleDiv.js,ToggleImg.jsInclude("~/Scripts/Common/T*.js")无效的模式的异常。通配符字符只允许对的前缀或后缀。Include("~/Scripts/Common/*og.*")无效的模式的异常。只有一个通配符字符被允许。"Include("~/Scripts/Common/T*")ToggleDiv.js ToggleImg.js"Include("~/Scripts/Common/*")无效的模式的异常。一个纯通配符段不是有效的。IncludeDirectory ("~/Scripts/Common","T *")ToggleDiv.js ToggleImg.jsIncludeDirectory("~/Scripts/Common", "T*",true)ToggleDiv.js,ToggleImg.js,ToggleLinks.js

显式地将每个文件添加到一捆是一般首选在通配符加载的文件,原因如下:

  • 将脚本由通配符默认值添加到加载它们按字母顺序,通常不是你想。经常需要 (非字母) 按照特定的顺序添加 CSS 和 JavaScript 文件。通过添加一个自定义的IBundleOrderer实现,但显式添加每个文件都少出错,可以降低这种风险。例如,您可能会添加新的资产到文件夹在将来可能会要求您修改您的IBundleOrderer实现。
  • 查看特定文件添加到使用通配符加载目录可以包含在引用该捆绑包的所有视图。如果查看特定脚本添加到包中,你可能会引用捆绑其他视图上一个 JavaScript 错误。
  • 将其他文件导入的 CSS 文件导致两次加载导入的文件。例如,下面的代码创建一个束与大多数的 jQuery UI 的主题 CSS 文件加载两次。
    bundles.Add(new StyleBundle("~/jQueryUI/themes/baseAll")    .IncludeDirectory("~/Content/themes/base", "*.css"));
    在每个 CSS 文件夹中的文件,包括Content\themes\base\jquery.ui.all.css文件带来的通配符"*.css"选择器。Jquery.ui.all.css文件中导入其他 CSS 文件。


原文:

Using Bundling and Minification with ASP.NET MVC

In this section we will create an ASP.NET MVC project to examine bundling and minification. First, create a new ASP.NET MVC internet project namedMvcBM without changing any of the defaults.

Open the App_Start\BundleConfig.cs file and examine the RegisterBundlesmethod which is used to create, register and configure bundles. The following code shows a portion of theRegisterBundles method.

 public static void RegisterBundles(BundleCollection bundles){     bundles.Add(new ScriptBundle("~/bundles/jquery").Include(                 "~/Scripts/jquery-{version}.js"));         // Code removed for clarity.}

The preceding code creates a new JavaScript bundle named ~/bundles/jquery that includes all the appropriate (that is debug or minified but not .vsdoc) files in theScripts folder that match the wild card string "~/Scripts/jquery-{version}.js". For ASP.NET MVC 4, this means with a debug configuration, the filejquery-1.7.1.js will be added to the bundle. In a release configuration,jquery-1.7.1.min.js will be added. The bundling framework follows several common conventions such as:

  • Selecting “.min” file for release when “FileX.min.js” and “FileX.js” exist.
  • Selecting the non “.min” version for debug.
  • Ignoring “-vsdoc” files (such as jquery-1.7.1-vsdoc.js), which are used only by IntelliSense.

The {version} wild card matching shown above is used to automatically create a jQuery bundle with the appropriate version of jQuery in yourScripts folder. In this example, using a wild card provides the following benefits:

  • Allows you to use NuGet to update to a newer jQuery version without changing the preceding bundling code or jQuery references in your view pages.
  • Automatically selects the full version for debug configurations and the ".min" version for release builds.

Using a CDN

The follow code replaces the local jQuery bundle with a CDN jQuery bundle.

public static void RegisterBundles(BundleCollection bundles){    //bundles.Add(new ScriptBundle("~/bundles/jquery").Include(    //            "~/Scripts/jquery-{version}.js"));    bundles.UseCdn = true;   //enable CDN support    //add link to jquery on the CDN    var jqueryCdnPath = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js";    bundles.Add(new ScriptBundle("~/bundles/jquery",                jqueryCdnPath).Include(                "~/Scripts/jquery-{version}.js"));    // Code removed for clarity.}

In the code above, jQuery will be requested from the CDN while in release mode and the debug version of jQuery will be fetched locally in debug mode. When using a CDN, you should have a fallback mechanism in case the CDN request fails. The following markup fragment from the end of the layout file shows script added to request jQuery should the CDN fail.

        </footer>        @Scripts.Render("~/bundles/jquery")        <script type="text/javascript">            if (typeof jQuery == 'undefined') {                var e = document.createElement('script');                e.src = '@Url.Content("~/Scripts/jquery-1.7.1.js")';                e.type = 'text/javascript';                document.getElementsByTagName("head")[0].appendChild(e);            }        </script>         @RenderSection("scripts", required: false)    </body></html>

Creating a Bundle

The Bundle class Include method takes an array of strings, where each string is a virtual path to resource. The following code from the RegisterBundles method in theApp_Start\BundleConfig.cs file shows how multiple files are added to a bundle:

bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(          "~/Content/themes/base/jquery.ui.core.css",          "~/Content/themes/base/jquery.ui.resizable.css",          "~/Content/themes/base/jquery.ui.selectable.css",          "~/Content/themes/base/jquery.ui.accordion.css",          "~/Content/themes/base/jquery.ui.autocomplete.css",          "~/Content/themes/base/jquery.ui.button.css",          "~/Content/themes/base/jquery.ui.dialog.css",          "~/Content/themes/base/jquery.ui.slider.css",          "~/Content/themes/base/jquery.ui.tabs.css",          "~/Content/themes/base/jquery.ui.datepicker.css",          "~/Content/themes/base/jquery.ui.progressbar.css",          "~/Content/themes/base/jquery.ui.theme.css"));

The Bundle class IncludeDirectory method is provided to add all the files in a directory (and optionally all subdirectories) which match a search pattern. TheBundle class IncludeDirectory API is shown below:

 public Bundle IncludeDirectory(     string directoryVirtualPath,  // The Virtual Path for the directory.     string searchPattern)         // The search pattern.  public Bundle IncludeDirectory(     string directoryVirtualPath,  // The Virtual Path for the directory.     string searchPattern,         // The search pattern.     bool searchSubdirectories)    // true to search subdirectories.

Bundles are referenced in views using the Render method , ( Styles.Render for CSS andScripts.Render for JavaScript). The following markup from the Views\Shared\_Layout.cshtml file shows how the default ASP.NET internet project views reference CSS and JavaScript bundles.

<!DOCTYPE html><html lang="en"><head>    @* Markup removed for clarity.*@        @Styles.Render("~/Content/themes/base/css", "~/Content/css")    @Scripts.Render("~/bundles/modernizr")</head><body>    @* Markup removed for clarity.*@      @Scripts.Render("~/bundles/jquery")   @RenderSection("scripts", required: false)</body></html>

Notice the Render methods takes an array of strings, so you can add multiple bundles in one line of code. You will generally want to use the Render methods which create the necessary HTML to reference the asset. You can use theUrl method to generate the URL to the asset without the markup needed to reference the asset. Suppose you wanted to use the new HTML5async attribute. The following code shows how to reference modernizr using theUrl method.

<head>    @*Markup removed for clarity*@    <meta charset="utf-8" />    <title>@ViewBag.Title - MVC 4 B/M</title>    <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />    <meta name="viewport" content="width=device-width" />    @Styles.Render("~/Content/css")   @* @Scripts.Render("~/bundles/modernizr")*@    <script src='@Scripts.Url("~/bundles/modernizr")' async> </script></head>

Using the "*" Wildcard Character to Select Files

The virtual path specified in the Include method and the search pattern in theIncludeDirectory method can accept one "*" wildcard character as a prefix or suffix to in the last path segment. The search string is case insensitive. TheIncludeDirectory method has the option of searching subdirectories.

Consider a project with the following JavaScript files:

  • Scripts\Common\AddAltToImg.js
  • Scripts\Common\ToggleDiv.js
  • Scripts\Common\ToggleImg.js
  • Scripts\Common\Sub1\ToggleLinks.js

dir imag

The following table shows the files added to a bundle using the wildcard as shown:

CallFiles Added or Exception RaisedInclude("~/Scripts/Common/*.js")AddAltToImg.js, ToggleDiv.js, ToggleImg.jsInclude("~/Scripts/Common/T*.js")Invalid pattern exception. The wildcard character is only allowed on the prefix or suffix.Include("~/Scripts/Common/*og.*")Invalid pattern exception. Only one wildcard character is allowed."Include("~/Scripts/Common/T*")ToggleDiv.js, ToggleImg.js"Include("~/Scripts/Common/*")Invalid pattern exception. A pure wildcard segment is not valid.IncludeDirectory("~/Scripts/Common", "T*")ToggleDiv.js, ToggleImg.jsIncludeDirectory("~/Scripts/Common", "T*",true)ToggleDiv.js, ToggleImg.js, ToggleLinks.js

Explicitly adding each file to a bundle is generally the preferred over wildcard loading of files for the following reasons:

  • Adding scripts by wildcard defaults to loading them in alphabetical order, which is typically not what you want. CSS and JavaScript files frequently need to be added in a specific (non-alphabetic) order. You can mitigate this risk by adding a customIBundleOrderer implementation, but explicitly adding each file is less error prone. For example, you might add new assets to a folder in the future which might require you to modify yourIBundleOrderer implementation.
  • View specific files added to a directory using wild card loading can be included in all views referencing that bundle. If the view specific script is added to a bundle, you may get a JavaScript error on other views that reference the bundle.
  • CSS files that import other files result in the imported files loaded twice. For example, the following code creates a bundle with most of the jQuery UI theme CSS files loaded twice.
    bundles.Add(new StyleBundle("~/jQueryUI/themes/baseAll")    .IncludeDirectory("~/Content/themes/base", "*.css"));
    The wild card selector "*.css" brings in each CSS file in the folder, including theContent\themes\base\jquery.ui.all.css file. The jquery.ui.all.css file imports other CSS files.
原创粉丝点击