MVC4 System.Web.Optimization 1.0 ScriptBundle機能 を試しています。
次の構成があります。
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
// shared scripts
Bundle canvasScripts =
new ScriptBundle(BundlePaths.CanvasScripts)
.Include("~/Scripts/modernizr-*")
.Include("~/Scripts/json2.js")
.Include("~/Scripts/columnizer.js")
.Include("~/Scripts/jquery.ui.message.min.js")
.Include("~/Scripts/Shared/achievements.js")
.Include("~/Scripts/Shared/canvas.js");
bundles.Add(canvasScripts);
}
}
次のビュー:
<script type="text/javascript" src="@Scripts.Url(BundlePaths.CanvasScripts)"></script>
ここで、BundlePaths.CanvasScripts
は"~/bundles/scripts/canvas"
です。これをレンダリングします:
<script type="text/javascript" src="/bundles/scripts/canvas?v=UTH3XqH0UXWjJzi-gtX03eU183BJNpFNg8anioG14_41"></script>
これまでのところ、~/Scripts/Shared/achievements.js
がバンドルされたソースの最初のスクリプトであることを除いて、これで十分です。 ScriptBundle
でその前に含まれるすべてのスクリプトに依存します。 バンドルにincludeステートメントを追加する順序を確実に順守するにはどうすればよいですか?
更新
これは比較的新しいASP.NET MVC 4アプリケーションでしたが、最適化フレームワークのプレリリースパッケージを参照していました。それを削除し、 http://nuget.org/packages/Microsoft.AspNet.Web.Optimization からRTMパッケージを追加しました。 web.configでdebug = trueを指定したRTMバージョンでは、@Scripts.Render("~/bundles/scripts/canvas")
は個々のスクリプトタグを正しい順序でレンダリングします。
Web.configでdebug = falseを使用すると、結合スクリプトには最初にachievements.jsスクリプトが含まれますが、後で呼び出される関数定義(オブジェクトコンストラクター)であるため、エラーなしで実行されます。おそらく、ミニファイナーは依存関係を把握するのに十分スマートですか?
また、Darin DimitrovがRTMで提案したIBundleOrderer
実装を両方のデバッグオプションで試してみましたが、同じ動作をしました。
したがって、縮小版は期待した順序ではありませんが、機能します。
RTMビットでこの動作は見られません。MicrosoftASP.NET Web Optimization Framework 1.0.0ビットを使用していますか? http://nuget.org/packages/Microsoft。 AspNet.Web.Optimization ?
新しいMVC4インターネットアプリケーションWebサイトに基づいて、サンプルと同様の再現を使用しました。
BundleConfig.RegisterBundlesに追加しました:
Bundle canvasScripts =
new ScriptBundle("~/bundles/scripts/canvas")
.Include("~/Scripts/modernizr-*")
.Include("~/Scripts/Shared/achievements.js")
.Include("~/Scripts/Shared/canvas.js");
bundles.Add(canvasScripts);
そして、デフォルトのインデックスページに、次を追加しました:
<script src="@Scripts.Url("~/bundles/scripts/canvas")"></script>
そして、バンドルの縮小されたjavascriptで、achievements.jsの内容がmodernizrの後にあることを確認しました...
バンドルが登録した順序に含まれるように、カスタムバンドル注文者( IBundleOrderer
)を作成できます。
public class AsIsBundleOrderer : IBundleOrderer
{
public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
{
return files;
}
}
その後:
public class BundleConfig
{
public static void RegisterBundles(BundleCollection bundles)
{
var bundle = new Bundle("~/bundles/scripts/canvas");
bundle.Orderer = new AsIsBundleOrderer();
bundle
.Include("~/Scripts/modernizr-*")
.Include("~/Scripts/json2.js")
.Include("~/Scripts/columnizer.js")
.Include("~/Scripts/jquery.ui.message.min.js")
.Include("~/Scripts/Shared/achievements.js")
.Include("~/Scripts/Shared/canvas.js");
bundles.Add(bundle);
}
}
そしてあなたの意見では:
@Scripts.Render("~/bundles/scripts/canvas")
ダリン、ありがとう。拡張メソッドを追加しました。
internal class AsIsBundleOrderer : IBundleOrderer
{
public virtual IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
{
return files;
}
}
internal static class BundleExtensions
{
public static Bundle ForceOrdered(this Bundle sb)
{
sb.Orderer = new AsIsBundleOrderer();
return sb;
}
}
使用法
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js",
"~/Scripts/jquery-migrate-{version}.js",
"~/Scripts/jquery.validate.js",
"~/Scripts/jquery.validate.messages_fr.js",
"~/Scripts/moon.jquery.validation-{version}.js",
"~/Scripts/jquery-ui-{version}.js"
).ForceOrdered());
SoftLionが提供する回答を更新して、MVC 5(BundleFileとFileInfo)の変更を処理しました。
internal class AsIsBundleOrderer : IBundleOrderer
{
public virtual IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
{
return files;
}
}
internal static class BundleExtensions
{
public static Bundle ForceOrdered(this Bundle sb)
{
sb.Orderer = new AsIsBundleOrderer();
return sb;
}
}
使用法:
bundles.Add(new ScriptBundle("~/content/js/site")
.Include("~/content/scripts/jquery-{version}.js")
.Include("~/content/scripts/bootstrap-{version}.js")
.Include("~/content/scripts/jquery.validate-{version}")
.ForceOrdered());
流れるような構文を使用するのが好きですが、単一のメソッド呼び出しとパラメーターとして渡されるすべてのスクリプトでも機能します。
BundleCollection.FileSetOrderListを使用して順序を設定できるはずです。このブログ投稿をご覧ください: http://weblogs.asp.net/imranbaloch/archive/2012/09/30/hidden-options-of-asp-net-bundling-and-minification.aspx 。インスタンスのコードは次のようになります。
BundleFileSetOrdering bundleFileSetOrdering = new BundleFileSetOrdering("js");
bundleFileSetOrdering.Files.Add("~/Scripts/modernizr-*");
bundleFileSetOrdering.Files.Add("~/Scripts/json2.js");
bundleFileSetOrdering.Files.Add("~/Scripts/columnizer.js");
bundleFileSetOrdering.Files.Add("~/Scripts/jquery.ui.message.min.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/achievements.js");
bundleFileSetOrdering.Files.Add("~/Scripts/Shared/canvas.js");
bundles.FileSetOrderList.Add(bundleFileSetOrdering);
カセット http://getcassette.net/ の使用を検討する必要があります。各ファイル内で見つかったスクリプト参照に基づいて、スクリプトの依存関係の自動検出をサポートします。
MS Web最適化ソリューションに固執するが、スクリプト参照に基づいてスクリプトを配置するアイデアが好きな場合は、 http://blogs.Microsoft.co.il/oric/のブログ投稿を読んでください。 2013/12/27/building-single-page-application-bundle-orderer /
@Darin Dimitrovの答えは私にとって完璧に機能しますが、私のプロジェクトはVBで書かれているので、ここに彼の答えをVBに変換しました
Public Class AsIsBundleOrderer
Implements IBundleOrderer
Public Function IBundleOrderer_OrderFiles(ByVal context As BundleContext, ByVal files As IEnumerable(Of FileInfo)) As IEnumerable(Of FileInfo) Implements IBundleOrderer.OrderFiles
Return files
End Function
End Class
使用するには:
Dim scriptBundleMain = New ScriptBundle("~/Scripts/myBundle")
scriptBundleMain.Orderer = New AsIsBundleOrderer()
scriptBundleMain.Include(
"~/Scripts/file1.js",
"~/Scripts/file2.js"
)
bundles.Add(scriptBundleMain)