UrlRewritingCssPostProcessor: wrong path resolution in imported files

Apr 28, 2016 at 8:08 PM
Since version 1.9 urls in imported LESS/SASS files are not absolutized correctly anymore. The base path must actually be the path of the imported file, not the root file. Example:

Root file /Themes/MyTheme/theme.less:
@import '~/Content/select2/select2.less'; // "/Content/select2" should be the base path for url rewriting
@import '../../Content/utils.less'; // "/Content" should be the base path for url rewriting
But in both cases above the base path is /Themes/MyTheme, the path of the root file theme.less. This inevitably leads to wrong path resolution and a HTTP 404 in the resulting output.
Apr 29, 2016 at 10:17 AM
Hello, Murat!

UrlRewritingCssPostProcessor is not being used to resolve LESS/SASS imports. Resolving of LESS/SASS imports is made at level of the BundleTransformer.Less and BundleTransformer.SassAndScss modules.

Your result of compilation of /Themes/MyTheme/theme.less file is not possible in principle, because content of imported LESS files are included in main LESS file.

I reproduced your example and got a absolutely correct result. I don't know what is cause of such errors. It is possible, that such errors can be caused by your implementation of VirtualPathProvider.

P.S.: By default UrlRewritingCssPostProcessor is not used in the debugging HTTP-handlers.
Apr 29, 2016 at 6:59 PM
Edited Apr 29, 2016 at 7:00 PM
Hello Andrey,

I was afraid that this won't work anymore due to the refactorings in version 1.9. To be more precise: the url rewrite must happen BEFORE the LESS/SASS file gets translated, one by one. I suppose this is how it worked before version 1.9. Because now, urls get rewritten AFTER all import files has been combined into the root file, thus loosing all path information of the imported files. But these are essential if you want to successfully rewrite a path within an imported file.

Example file structure:
    |     |---sprite.png
Imagine, sprite.png is referred as url('images/sprite.png') within select2.less... which is absolutely correct at this stage, because select2 is a self-contained vendor folder. But after the translation of theme.less the path still is images/sprite.png, which is wrong: it has to be select2/images/sprite.png, because select2.less has gone! It's content has been merged into theme.less which - in this case - sits in a different folder than select2.less.

This applies to both debug and release modes. In debug mode, urls stay untouched by default. In release mode however, the path gets rewritten to something like /Themes/MyTheme/images/sprite.png, but it has to be /Themes/MyTheme/select2/images/sprite.png (the select2 part is missing).

I hope I could clarify the problem. I googled a bit and found out that libSass users seem to have the same problem. They bypass this by - for example - using node.js preprocessors, which unfortunately is not an option for us.
Apr 29, 2016 at 7:34 PM
OK, next week I will look for cause of this problem.
May 3, 2016 at 7:17 PM
Hello, Murat!

In Bundle Transformer 1.9.105 solved problem with LESS.
I googled a bit and found out that libSass users seem to have the same problem.
Ruby Sass and libSass initially does not support the resolution of CSS component paths (images, fonts, etc). Earlier in the BundleTransformer.Less, BundleTransformer.SassAndScss and BundleTransformer.TypeScript modules was used own preprocessing, but it broke interpolation. On this occasion, I received a lot of complaints from users. In 1.9.81 and 1.9.92 versions have solved these problems.

Therefore, I recommend you to adapt to existing Sass constraints.
May 4, 2016 at 5:49 PM
Edited May 4, 2016 at 6:12 PM
That's too bad, because we won't be using LESS anymore! This also means massive restructuring of our theming mechanism (folder structure etc.), which actually is a no-go. I'll have to figure out something else.
May 4, 2016 at 5:58 PM
Try to somehow influence to Sass authors.