バンドラーは.minファイルを含みません


261

拡張子.min.jsのファイルが含まれていないmvc4バンドラーに奇妙な問題があります

私のBundleConfigクラスで、私は宣言します

public static void RegisterBundles(BundleCollection bundles)
{
    bundles.Add(new ScriptBundle("~/Scripts/jquery")
        .Include("~/Scripts/jquery-1.8.0.js")
        .Include("~/Scripts/jquery.tmpl.min.js"));            
}

私の見解では、私は宣言します

<html>
    <head>
    @Scripts.Render("~/Scripts/jquery")
    </head><body>test</body>
</html>

そしてそれがレンダリングするとき、それはレンダリングするだけです

<html>
    <head>
         <script src="/Scripts/jquery-1.8.0.js"></script>
    </head>
    <body>test</body>
</html>

jquery.tmpl.min.jsの名前をjquery.tmpl.jsに変更すると(それに応じてバンドルのパスを更新すると)、両方のスクリプトが正しくレンダリングされます。

「.min.js」ファイルを無視する原因となっている構成設定はありますか?


私はMVC 4バンドルを使用しており、.min.jsファイルが含まれています。
エリックJ.

RTMバージョンまたはRC?それはあまりにも私のためにRCで[OK]を働いていた
致命的な

10
アイデアは、デバッグモードでの作業、縮小なしの「dev」バージョンが使用される、非デバッグモードの場合は縮小バージョンが選択される、というものです。実際の動作を確認するには、web.configデバッグ値をtrueからfalseに変更します。
Pieter Germishuys、2012

28
ただし、場合によっては、スクリプトの縮小版ではないこともあります。両方のファイルが存在する場合、私はおそらくそれを理解できました。
致命的

1
デフォルトでこのように機能するのは残念です...確かに、ファイルはすでに縮小されている可能性がありますが、Microsoftは、キャッシュ無効化の目的でバンドルに事前に縮小されたスクリプトを追加するメリットを確認できなかったと思います(素敵な小さなvパラメーターハッシュ)それは、URLに追加し、変更があったとき、ファイルの内容の変更)
nothingisnecessary

回答:


257

私が最初に投稿したソリューションは疑わしいです(汚いハックです)。微調整された動作はMicrosoft.AspNet.Web.Optimizationパッケージで変更され、多くのコメント投稿者から指摘されているように、微調整は機能しなくなりました。現在、パッケージのバージョン1.1.3では問題をまったく再現できません。

System.Web.Optimization.BundleCollectionのソース(たとえば、dotPeekを使用できます)を参照して、実行しようとしていることをよく理解してください。また、読みマックスShmelevの答えを

元の答え

.min.jsの名前を.jsに変更するか、次のようにします。

    public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
    {
        if (ignoreList == null)
            throw new ArgumentNullException("ignoreList");
        ignoreList.Ignore("*.intellisense.js");
        ignoreList.Ignore("*-vsdoc.js");
        ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
        //ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
        ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
    }

    public static void RegisterBundles(BundleCollection bundles)
    {
        bundles.IgnoreList.Clear();
        AddDefaultIgnorePatterns(bundles.IgnoreList);
        //NOTE: it's bundles.DirectoryFilter in Microsoft.AspNet.Web.Optimization.1.1.3 and not bundles.IgnoreList

        //...your code
     }

4
私もありがとう-これを私のMVC4取得リストに追加します:)
Dan B

27
これは長いwtfの瞬間でした。理由や何かの結果でコメントアウトされたこれらのminファイルを追加していた可能性があり、誰が出力からスクリプトファイルを盗んでいるのか疑問に思って丸1時間無駄になりました。
Giedrius

5
OPでのFatalのコメントによると、このソリューションは、縮小バージョンと通常バージョンの両方が存在する場合(jqueryなど)、両方の参照が重複して再利用されることになります。
danmiser 2012

11
M $、somefile.min.jsが明示的に指定されている場合、または.min.jsファイルのみが存在する場合は、.min.jsファイルのみを含めます。それ以外の場合は、現在の動作を適用してください!
Adaptabi 2013年

3
実際のクラスは "IgnoreList"と呼ばれていますが、Objectから直接派生しています。LINQなし、反復なし。- msdn.microsoft.com/en-us/library/...
JP 10ベルゲ

176

マイクロソフトは以下の動作を示唆しています(私は自分のプロジェクトでそれに従うことを好みます)。

短縮版

  1. プロジェクトのスクリプトのデバッグバージョンと縮小バージョンの両方が同じフォルダーにあります。
    • script.js
    • script.min.js
  2. コードのバンドルにscript.jsのみを追加します。

その結果、script.jsDEBUGモードに含まれ、script.min.jsRELEASEモードに自動的に含まれます。

ロングバージョン

.debug.jsバージョンも使用できます。その場合、ファイルはDEBUGの次の優先順位に含まれます。

  1. script.debug.js
  2. script.js

リリース:

  1. script.min.js
  2. script.js

注意

ちなみに、MVC4でスクリプトの.minバージョンを使用する唯一の理由は、縮小バージョンを自動的に処理できない場合です。たとえば、次のコードは自動的に難読化できません。

if (DEBUG) console.log("Debug message");

他のすべてのケースでは、スクリプトのデバッグバージョンだけで実行できます。


6
いい説明ですが、OPの問題は、一部のスクリプト(jquery.tmpl)に、ファイルの最小バージョンではないバージョンがダウンロードされていない、付属していない、ということです。デバッグモードで非最小バージョンがない場合、バンドラーはスクリプトファイルを完全に無視します
Eonasdan

そうですね、いい説明ですが、OPの質問にはまったく答えません。
ディエゴ

2
ショートバージョンではうまくいきませんでした。「script.js」は、これらのリリースタイプの両方に含まれます。DEBUG / RELEASEを切り替え、(ソースを見ると) 'script.js'が選択/レンダリングされたものでした。
user981375 2012年

4
user981375、web.configファイルで<compilation debug = "false" />も設定する必要があります
Max Shmelev

5
これは「ベストプラクティス」のアプローチであり、同じ目的を達成するためにバンドラーのデフォルトルールに従う方法を説明しているため、私はこの回答を好みます。
James Reategui 2013年

5

あなたが持っているものがすべてファイルの縮小バージョンである場合、私が見つけた最も簡単な解決策は、縮小ファイルをコピーし、コピーしたファイルの名前から.minを削除してから、バンドル内の非縮小ファイル名を参照することです。

たとえば、jsコンポーネントを購入し、some-lib-3.2.1.min.jsというファイルを提供したとします。このファイルをバンドルで使用するには、次のようにします。

  1. some-lib-3.2.1.min.jsをコピーし、コピーしたファイルの名前をsome-lib-3.2.1.jsに変更します。プロジェクトに両方のファイルを含めます。

  2. 次のように、バンドル内の縮小されていないファイルを参照します。

    bundles.Add(new ScriptBundle("~/bundles/libraries").Include(
        "~/Scripts/some-lib-{version}.js"
    ));

名前に「min」が含まれていないファイルが実際に縮小されているからといって、問題が発生することはありません(それが本質的に読み取り不可能であるという事実を除きます)。デバッグモードでのみ使用され、別のスクリプトとして書き出されます。デバッグモードでない場合、プリコンパイルされたminファイルがバンドルに含まれている必要があります。


4

少なくともMVC5で機能する優れたソリューションを見つけました。Bundle代わりにを使用できますScriptBundleScriptBundleこの場合、(。minなどを無視して)気に入らないスマートな動作はありません。私のソリューションではBundle、.minファイルと.mapファイルを含む3Dパーティースクリプトに使用ScriptBundleし、コードに使用しています。私はそれをすることのどんな欠点にも気づきませんでした。この方法で機能させるには、元のファイル(angular.jsなど)を追加する必要があります。これにより、angular.jsがデバッグで読み込まれ、angular.min.jsがリリースモードでバンドルされます。


最適化が無効になっていると機能しないようです(ScriptTable.EnableOptimizations = false)。パターンを含むスクリプトパスはレンダリングされません(例:)~/Scripts/thirdpartylib/*.js。それ動作EnableOptimizations = trueScriptBundleますが、動作します。
Steven Liekens

私は(開発中)falseでも使用していますが、あなたが説明する問題はないので、他の何かが影響している可能性があります。パターンを機能させるには、includeではなくIncludeDirectoryを実行する必要もあります。
Ilya Chernomordik

「.min.js」バージョンのファイルをレンダリングしていますか?名前空間System.Web.Optimizationsまたはnugetパッケージのバンドルを使用していますかMicrosoft.Web.Optimizations
Steven Liekens

私はSystem.Web.Optimizationを使用し、それが最小バージョンをレンダリングすることを確認しましたが、実際にはIncludeDirectoryを使用していないことがわかりましたが、それが最小バージョンで機能しない場合は不思議です... IncludeDirectoryはカスタムスキャンを実行し、Includeを使用してすべてのフィルターを追加するのに十分なので、パターンとIncludeDirectoryがそこで正しく機能しない可能性がありますが、少し奇妙です。
Ilya Chernomordik

1
いいえ、問題は2つあり.min.jsます。ファイルのみが存在し、*.jsパターンが末尾がのファイルと一致しません.min.js
Steven Liekens

3

*.min.jsファイルをレンダリングするにBundleTable.EnableOptimizationsは、無効にする必要があります。これは、すべてのバンドルに適用されるグローバル設定です。

特定のバンドルのみの最適化を有効にする場合ScriptBundleは、バンドル内のファイルを列挙するときに一時的に最適化を有効にする独自のタイプを作成できます。

public class OptimizedScriptBundle : ScriptBundle
{
    public OptimizedScriptBundle(string virtualPath)
        : base(virtualPath)
    {
    }

    public OptimizedScriptBundle(string virtualPath, string cdnPath)
        : base(virtualPath, cdnPath)
    {
    }

    public override IEnumerable<BundleFile> EnumerateFiles(BundleContext context)
    {
        if (context.EnableOptimizations)
            return base.EnumerateFiles(context);
        try
        {
            context.EnableOptimizations = true;
            return base.EnumerateFiles(context);
        }
        finally
        {
            context.EnableOptimizations = false;
        }
    }
}

ミニファイされていないファイルが存在するかどうかに関係なく、常にミニファイされたファイルを使用する必要があるバンドルのOptimizedScriptBundle代わりに使用しScriptBundleます。

縮小ファイルのみのコレクションとして配布される、Kendo UI for ASP.NET MVCの例。

bundles.Add(new OptimizedScriptBundle("~/bundles/kendo")
        .Include(
            "~/Scripts/kendo/kendo.all.*",
            "~/Scripts/kendo/kendo.aspnetmvc.*",
            "~/Scripts/kendo/cultures/kendo.*",
            "~/Scripts/kendo/messages/kendo.*"));

プロダクションのパブリッシュアクションで不足しているスクリプトに出くわし、それをMVCの問題だと思ったので、この答えを見つけました。あまりにも長い間働いていたので、私は剣道から逃れるために何でもします
フェリペ

@Felipe私は同じ状況にいたので、この回答を書きました。剣道は恐ろしいです。私の例がお役に立てば幸いです。
Steven Liekens

2

私の場合、私は(素晴らしい!)Knockout.jsライブラリを使用していましたが、これはデバッグ/非バージョンとして提供されています:

"~/Scripts/knockout-{Version}.js"
"~/Scripts/knockout-{Version}.Debug.js"

これを機能させるために、バンドルに「Knockout- {Version} .js」(非デバッグ)を含め、.debugを取得しました。デバッグモードのjsファイル。


1

簡単な方法は、単に.minファイルの名前を変更するだけです。たとえば、abc.min.cssがある場合、このファイルの名前をabc_min.cssに変更してバンドルに追加するだけです。私はそれを行う正しい方法ではなく、一時的な解決策を知っています。感謝と幸せなコーディング。


1
nugetがファイルをダウンロードするたびに、名前を変更する必要があります。
Anirudha Gupta

私はそれを行う正しい方法ではなく、一時的な解決策を知っています
RK Sharma

1
この行が私のために働いていると言う// BundleTable.EnableOptimizations = true;
Anirudha Gupta

0

バンドラーには多くの利点がありますこのページをチェックしてください しかし

Microsoft MVC4プラットフォームでは、各スクリプトまたはスタイルバンドルに少なくとも縮小バージョンと非縮小バージョンの両方があることを考慮しています(Debugやvsdocなどの別のファイルも利用できます)。したがって、これらのファイルが1つしかない状況では問題があります。

web.configファイルのデバッグ状態を永続的に変更して、出力を処理できます。

<compilation debug="false" targetFramework="4.0" />

出力の変更を確認してください!ファイルフィルタリングが変更されました。目的を満たすには、アプリケーションロジックを変更する無視ケースのフィルタリングを変更する必要があります。


1
debug = "false"を追加してもまだ機能しません。IgnoreListもクリアしてもmin.jsファイルはまだ含まれていません...
MoSs

-21

人々は私がそれがマイクロソフトが一緒に行動するようになるまで単にそれを保つだけです

これを試して

RegisterBundlesでこの剣道用のバンドルを作成します

bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
                    "~/Content/kendo/2012.3.1121/kendo.common.min.css",
                     "~/Content/kendo/2012.3.1121/kendo.dataviz.min.css",
                      "~/Content/kendo/2012.3.1121/kendo.blueopal.min.css"
 ));

_Layout.cshtmlにこれを入れてください:

@if (HttpContext.Current.IsDebuggingEnabled)
 { 
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.common.min.css")"      
rel="stylesheet"  type="text/css" />
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.dataviz.min.css")" 
rel="stylesheet" type="text/css" />   
<link href="@Url.Content("~/Content/kendo/2012.3.1121/kendo.blueopal.min.css")"    
rel="stylesheet" type="text/css" />
 }
 else
 {
     @Styles.Render("~/Content/kendo/css")   
 }

このようにして、本番環境で最高のバンドルとデバッグで参照を取得します

MicrosoftがMVC 4コードを修正したら修正する


3
私はこの提案されたソリューションのファンではありません。これで、(少なくとも)2つの場所でのスクリプトのセットを維持するために抱えている
致命的な

これは結束の目的をかなり損なうと思いませんか?
オリバー

4
バンドルはすでにこの方法で機能しています。プロジェクトをデバッグモードで実行する場合、各CSSファイルは個別にロードされますが、リリースで実行すると、それらは結合されて1つに縮小されます。ifブロック内のコードは、デバッグモードでページに自動的にレンダリングされるコードと同じです。
Chad Levy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.