csslessasp.net-mvc-5bundletransformer

Stop Bundle Transformer converting relative paths in LESS


I am using Bundle Transformer for LESS compilation in an MVC5 project. My LESS bundle comprises a single main.less file which imports other files located in subfolders. Some of files contain references to image files like so - this is in the file /css/structure/header.less:

.site__logo {
    background: url('../img/logo.png') no-repeat;
    // ...
}

In the compiled bundle (/css/lessBundle) this becomes:

background: url('/css/img/logo.png') no-repeat;

I want the relative path in the .less file to be preserved when it is bundled so that it correctly points to /img/logo.png, not /css/img/logo.png. I think Bundle Transformer is responsible for converting the relative paths -- the documentation has this paragraph, but doesn't go into further detail:

You also need to understand that when you plug instances of CssTransformer and JsTransformer classes, then you plug in a set of transformations (choice between debug and pre-minified versions of files, translation code from the intermediate languages, runtime code minification, transformation of relative paths to absolute (only for CSS-code) and code combining). A set of transformations depends on what the modules of Bundle Transformer you have installed and settings you have specified in the Web.config file.

Here is my BundleConfig:

public class BundleConfig
{
    public const string LessBundlePath = "~/css/lessBundle";

    public static void RegisterBundles(BundleCollection bundles)
    {
        var nullBuilder = new NullBuilder();
        var cssTransformer = new CssTransformer();
        var nullOrderer = new NullOrderer();

        // Skip JS-related stuff

        var lessBundle = new Bundle(LessBundlePath)
            .Include("~/css/main.less");
        lessBundle.Builder = nullBuilder;
        lessBundle.Transforms.Add(cssTransformer);
        lessBundle.Orderer = nullOrderer;
        bundles.Add(lessBundle);

        BundleTable.EnableOptimizations = true;
    }
}

/css/main.less is mostly just a bunch of imports:

@import "bootstrap/bootstrap";
@import "structure/header";
// etc.

html, body {
height: 100%;
}

I have tried playing with this setting in web.config, but to no effect:

<css defaultMinifier="NullMinifier" disableNativeCssRelativePathTransformation="true">

If possible I would rather not alter the filepaths in the .less files, as they are provided by a third party and everything works fine on their integration server (which is not using .NET). Is there anything else I can do?


Solution

  • In the BundleTransformer.Less and BundleTransformer.SassAndScss modules cannot be disable transformation of relative paths to absolute, because it can break the references to images when using @import directives.

    To get /img/logo.png instead of /css/img/logo.png you just need to correctly specify a relative path in the source code (../../img/logo.png instead of ../img/logo.png).