web-dev-qa-db-fra.com

Bundler n'incluant pas les fichiers .min

J'ai un problème étrange avec le bundle mvc4 n'incluant pas les fichiers avec l'extension .min.js

Dans ma classe BundleConfig, je déclare

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"));            
}

À mon avis, je déclare

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

Et quand il rend, il ne rend que

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

Si je renomme jquery.tmpl.min.js en jquery.tmpl.js (et que je mets le chemin à jour en conséquence), les deux scripts sont correctement rendus.

Existe-t-il des paramètres de configuration qui l'ignorent? '.Min.js'?

260
Fatal

La solution que j'ai initialement publiée est discutable (c'est un sale bidouillage). Le comportement modifié a été modifié dans le package Microsoft.AspNet.Web.Optimization et le Tweak ne fonctionne plus, comme l'ont souligné de nombreux commentateurs. Pour le moment, je ne peux pas reproduire le problème du tout avec la version 1.1.3 du paquet.

Veuillez consulter les sources de System.Web.Optimization.BundleCollection (vous pouvez utiliser dotPeek par exemple) pour mieux comprendre ce que vous êtes sur le point de faire. Lisez aussi réponse de Max Shmelev .

Réponse originale :

Renommez .min.js en .js ou faites quelque chose comme:

    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
     }
255
Pavel

Microsoft implique le comportement suivant (et je préfère le suivre dans mes projets):

version courte

  1. Vous avez des versions à la fois miniatures et de débogage d'un script dans votre projet sous le même dossier:
    • script.js
    • script.min.js
  2. Vous ajoutez uniquement script.js à un ensemble dans votre code.

En conséquence, vous aurez automatiquement le mode script.js inclus dans DEBUG et script.min.js = en mode RELEASE.

version longue

Vous pouvez aussi avoir . Debug.js version. Dans ce cas, le fichier est inclus dans la priorité suivante dans DEBUG:

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

en version:

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

remarque

Et au fait, la seule raison d'avoir une version . Min de vos scripts dans MVC4 est le cas où la version réduite ne peut pas être traitée automatiquement. Par exemple, le code suivant ne peut pas être obscurci automatiquement:

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

Dans tous les autres cas, vous pouvez utiliser uniquement une version de débogage de votre script.

176
Max Shmelev

Si tout ce que vous avez est une version minifiée d'un fichier, la solution la plus simple que j'ai trouvée consiste à copier le fichier minifié, à supprimer .min du nom du fichier copié, puis à référencer le nom du fichier non minifié dans votre lot.

Par exemple, supposons que vous ayez acheté un composant js et qu’ils vous aient attribué un fichier nommé some-lib-3.2.1.min.js. Pour utiliser ce fichier dans un lot, procédez comme suit:

  1. Copiez some-lib-3.2.1.min.js et renommez le fichier copié en some-lib-3.2.1.js. Inclure les deux fichiers dans votre projet.

  2. Référencez le fichier non minifié dans votre paquet, comme ceci:

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

Ce n'est pas parce que le fichier sans "min" dans le nom est minifié que cela ne pose aucun problème (à part le fait qu'il soit essentiellement illisible). Il n'est utilisé qu'en mode débogage et est écrit en tant que script séparé. Lorsqu'il n'est pas en mode débogage, le fichier pré-compilé doit être inclus dans votre paquet.

5
joelfp

J'ai trouvé une bonne solution qui fonctionne au moins dans MVC5, vous pouvez simplement utiliser Bundle au lieu de ScriptBundle. Il n'a pas le comportement intelligent de ScriptBundle que nous n'aimons pas (ignorer .min, etc.) dans ce cas. Dans ma solution, j'utilise Bundle pour les scripts de partie 3d avec les fichiers .min et .map et j'utilise ScriptBundle pour notre code. Je n'ai pas remarqué d'inconvénients à le faire. Pour que cela fonctionne de cette manière, vous devrez ajouter le fichier original, par exemple. angular.js, et il chargera angular.js dans le débogage et regroupera le fichier angular.min.js en mode de libération.

4
Ilya Chernomordik

Pour restituer les fichiers *.min.js, vous devez désactiver BundleTable.EnableOptimizations, qui est un paramètre global qui s'applique à tous les ensembles.

Si vous souhaitez activer les optimisations uniquement pour des ensembles spécifiques, vous pouvez créer votre propre type ScriptBundle qui active temporairement les optimisations lors de l'énumération des fichiers de l'ensemble.

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;
        }
    }
}

Utilisez OptimizedScriptBundle au lieu de ScriptBundle pour les ensembles dont le fichier minifié doit toujours être utilisé, qu'il existe ou non un fichier non minifié.

Exemple pour Kendo UI pour ASP.NET MVC, qui est distribué sous forme de collection de fichiers minifiés uniquement.

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

Pour mon cas, j'utilisais la (merveilleuse!) Bibliothèque Knockout.js qui existe sous la forme de versions Debug/Non:

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

Pour que cela fonctionne, j'ai inclus "Knockout- {Version} .js" (non-debug) dans mon Bundle et j'ai obtenu le .debug. fichier js en mode débogage.

2
AcidPAT

Renommez simplement le fichier .min. Par exemple, abc.min.css vous suffit de renommer ce fichier en abc_min.css et de l’ajouter à votre bundle. Je sais que ce n'est pas la bonne façon de le faire, mais une solution temporaire. merci et joyeux codage.

1
R K Sharma

Bundler a beaucoup d'avantages voir cette pageMAIS:

La plate-forme Microsoft MVC4 considère que vous avez au moins les versions minifiée et non modifiée pour chaque ensemble de scripts ou de styles (d'autres fichiers tels que Debug et vsdoc sont également disponibles). Nous avons donc du mal à trouver un seul fichier.

Vous pouvez modifier l'état de débogage dans le fichier web.config de manière permanente pour gérer la sortie:

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

Voir les changements de sortie! Le filtrage de fichiers a été modifié. Pour atteindre cet objectif, nous devons changer, ignorer la filtration de cas qui changera la logique de l'application!

0