在这一节我们将创建 ASP.NET MVC 项目,审查捆绑和缩小。首先,创建一个新的 ASP.NET MVC 互联网项目,命名为MvcBM ,而无需更改任何默认设置。
打开App_Start\BundleConfig.cs文件并检查的 RegisterBundles
方法,用于创建、 注册和配置包。下面的代码演示RegisterBundles
方法的部分。
publicstaticvoidRegisterBundles(BundleCollection bundles){ bundles.Add(newScriptBundle("~/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将被添加。捆绑框架如以下几个共同的约定:
如上所示的{version}
通配符匹配用于自动创建一个 jQuery 束具有适当版本的 jQuery脚本文件夹中。在此示例中,使用通配符提供了以下好处:
以下代码将使用 CDN jQuery 绑定来替换本地 jQuery 绑定。
publicstaticvoidRegisterBundles(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 CDNvar jqueryCdnPath ="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"; bundles.Add(newScriptBundle("~/bundles/jquery", jqueryCdnPath).Include("~/Scripts/jquery-{version}.js"));// Code removed for clarity.}
在上面的代码中,jQuery 将请求从 CDN 虽然在释放模式和 jQuery 的调试版本将被回迁本地在调试模式下。当使用 CDN,你应该有一个回退机制在 CDN 请求失败的情况下。下面的标记片段从布局文件的末尾显示脚本添加请求 jQuery 应 CDN 失败。
</footer> @Scripts.Render("~/bundles/jquery") <scripttype="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(newStyleBundle("~/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
方法被提供要添加一个目录 (和 (可选) 的所有子目录) 中与搜索模式匹配的所有文件。包类IncludeDirectory
API 如下所示:
publicBundleIncludeDirectory(string directoryVirtualPath,// The Virtual Path for the directory.string searchPattern)// The search pattern.publicBundleIncludeDirectory(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><htmllang="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,该资产,而引用该资产所需的标记。假设你想要使用新的 HTML5 async属性。下面的代码演示如何引用 modernizr 使用Url
的方法。
<head> @*Markup removed for clarity*@ <metacharset="utf-8"/><title>@ViewBag.Title - MVC 4 B/M</title><linkhref="~/favicon.ico"rel="shortcut icon"type="image/x-icon"/><metaname="viewport"content="width=device-width"/> @Styles.Render("~/Content/css") @* @Scripts.Render("~/bundles/modernizr")*@ <scriptsrc='@Scripts.Url("~/bundles/modernizr")'async></script></head>
Include
方法和IncludeDirectory
方法中的搜索模式中指定的虚拟路径可以接受一个"*"通配符字符作为前缀或后缀来中最后一个路径段。搜索字符串是区分大小写。IncludeDirectory
方法有选择搜索子目录。
与下面的 JavaScript 文件考虑一个项目:
下表显示的文件添加到捆绑使用通配符,如图所示:
电话 | 添加文件或引发异常 |
Include("~/Scripts/Common/*.js") | AddAltToImg.js,ToggleDiv.js,ToggleImg.js |
Include("~/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.js |
IncludeDirectory("~/Scripts/Common", "T*",true) | ToggleDiv.js,ToggleImg.js,ToggleLinks.js |
显式地将每个文件添加到一捆是一般首选在通配符加载的文件,原因如下:
bundles.Add(newStyleBundle("~/jQueryUI/themes/baseAll").IncludeDirectory("~/Content/themes/base","*.css"));在每个 CSS 文件夹中的文件,包括Content\themes\base\jquery.ui.all.css文件带来的通配符"*.css"选择器。Jquery.ui.all.css文件中导入其他 CSS 文件。
原文:
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 RegisterBundles
method which is used to create, register and configure bundles. The following code shows a portion of the RegisterBundles
method.
publicstaticvoidRegisterBundles(BundleCollection bundles){ bundles.Add(newScriptBundle("~/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 the Scripts folder that match the wild card string "~/Scripts/jquery-{version}.js". For ASP.NET MVC 4, this means with a debug configuration, the file jquery-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:
The {version}
wild card matching shown above is used to automatically create a jQuery bundle with the appropriate version of jQuery in your Scriptsfolder. In this example, using a wild card provides the following benefits:
The follow code replaces the local jQuery bundle with a CDN jQuery bundle.
publicstaticvoidRegisterBundles(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 CDNvar jqueryCdnPath ="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"; bundles.Add(newScriptBundle("~/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") <scripttype="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>
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 the App_Start\BundleConfig.cs file shows how multiple files are added to a bundle:
bundles.Add(newStyleBundle("~/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. The Bundle class IncludeDirectory
API is shown below:
publicBundleIncludeDirectory(string directoryVirtualPath,// The Virtual Path for the directory.string searchPattern)// The search pattern.publicBundleIncludeDirectory(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 and Scripts.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><htmllang="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 the Url
method to generate the URL to the asset without the markup needed to reference the asset. Suppose you wanted to use the new HTML5 async attribute. The following code shows how to reference modernizr using the Url
method.
<head> @*Markup removed for clarity*@ <metacharset="utf-8"/><title>@ViewBag.Title - MVC 4 B/M</title><linkhref="~/favicon.ico"rel="shortcut icon"type="image/x-icon"/><metaname="viewport"content="width=device-width"/> @Styles.Render("~/Content/css") @* @Scripts.Render("~/bundles/modernizr")*@ <scriptsrc='@Scripts.Url("~/bundles/modernizr")'async></script></head>
The virtual path specified in the Include
method and the search pattern in the IncludeDirectory
method can accept one "*" wildcard character as a prefix or suffix to in the last path segment. The search string is case insensitive. The IncludeDirectory
method has the option of searching subdirectories.
Consider a project with the following JavaScript files:
The following table shows the files added to a bundle using the wildcard as shown:
Call | Files Added or Exception Raised |
Include("~/Scripts/Common/*.js") | AddAltToImg.js, ToggleDiv.js, ToggleImg.js |
Include("~/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.js |
IncludeDirectory("~/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:
bundles.Add(newStyleBundle("~/jQueryUI/themes/baseAll").IncludeDirectory("~/Content/themes/base","*.css"));The wild card selector "*.css" brings in each CSS file in the folder, including the Content\themes\base\jquery.ui.all.css file. The jquery.ui.all.cssfile imports other CSS files.