Search code examples
c#asp.net-mvcbundling-and-minification

Ignoring files in MVC Bundles


We are using feature flags (set in Web.Config) to toggle the visibility in the UI of certain features that aren't yet complete. I'd also like my MVC bundles to NOT include the related JS files since they would just be useless files the client would have to download when the feature isn't enabled.

So far I've found IgnoreList.Ignore but I can't seem to get it to work. This is basically what I'm doing:

public static void RegisterBundles(BundleCollection bundles)
{
    if (!appConfiguration.FeatureXEnabled)
    {
        //Skip these files if the Feature X is not enabled!
        //When this flag is removed, these lines can be deleted and the files will be included like normal
        bundles.IgnoreList.Ignore("~/App/Organization/SomeCtrl.js", OptimizationMode.Always);
        bundles.IgnoreList.Ignore("~/App/Filters/SomeFilter.js", OptimizationMode.Always);
    }

    var globalBundle = new ScriptBundle("~/bundles/app-global").Include(
        "~/App/RootCtrl.js",
        "~/App/Directives/*.js",
        "~/App/Services/*.js",
        "~/App/Application.js"
    );
    bundles.Add(globalBundle);

    var appOrgBundle = new ScriptBundle("~/bundles/app-org");
    appOrgBundle.Include(
        "~/App/Filters/*.js",
        "~/App/Organization/*.js"
    );

    bundles.Add(appOrgBundle);
}

With the above code, the files in the ignore list are still being included! What am I doing wrong here?


Solution

  • I have fought the ignore list when using expressions as well. A simple work around I have found is to implement an IBundleOrderer that will exclude the files I do not want, and apply some ordering to how the files get included. Although this is not really its intended use, I find it fills the gap.

    The IBundleOrderer gets access to the full list of files (expression expanded to what files it matched).

    public class ApplicationOrderer : IBundleOrderer {
        public IEnumerable<BundleFile> OrderFiles(BundleContext context, IEnumerable<BundleFile> files)
        {
            if (!AppSettings.FeatureFlag_ServiceIntegrationsEnabled)
            {
                //Skip these files if the Service Integrations Feature is not enabled!
                //When this flag is removed, these lines can be deleted and the files will be included like normal
                var serviceIntegrationPathsToIgnore = new[]
                {
                    "/App/ServiceIntegrations/IntegrationSettingsModel.js",
                    "/App/ServiceIntegrations/IntegrationSettingsService.js",
                    "/App/ServiceIntegrations/ServiceIntegrationsCtrl.js"
                };
                files = files.Where(x => !serviceIntegrationPathsToIgnore.Contains(x.VirtualFile.VirtualPath));
            }
    
            return files;
        }
    }
    

    Example Usage:

    public static void RegisterBundles(BundleCollection bundles)
    {
            var appBundle = new ScriptBundle("~/bundles/app")
                .IncludeDirectory("~/App/", "*.js", true)
            appBundle.Orderer = new ApplicationOrderer();
            bundles.Add(appBundle);
    }