ASP.NET 5 and CSS bundling: Fixing image paths
With ASP.NET 5 we don’t have current bundling and minification system available. It’s replaced by new one that is based on Gulp. Default web application shows how to minify simple and safe files. But if you have some more complex design with CSS files referring to images then you are on your own. This post shows you how to solve a problem.
Not so trivial design
So, the image on right shows where things are getting bad with CSS. At least some of these CSS-files have references to images and my project has some components that refer to fonts too. And, of course, let’s not forget CSS imports.
Most of the URL-s are relative to location of CSS-file that has reference to them. When bundling CSS-files together then these paths are not valid anymore if there is no transform that fixes paths.
Default CSS minification script can’t handle this situation well because it doesn’t change URL-s of images, fonts and imports. It is safe to use if your CSS doesn’t have references to images and it doesn’t use imports that use relative URL-s.
After some hours in wonder-world of Gulp and JavaScript I was able to get my paths in CSS-files transformed correctly.
Solution for CSS
I tried to get path transforming work with css-min-css and clean-css but they both failed badly.To make image URL-s server relative I had to use one library that transforms paths and screws them up. After this I applied some string replacements and fixed the mess.
NB! JavaScript in the following code block and specially my mighty regex are far from perfect. I’m working mostly on C# code. If you have ideas how to improve the code then please leave your hints to comments. Thanks!
So, here is my Gulp file with JavaScript files stuff excluded:
/// <binding Clean=’clean’ />
var gulp = require(“gulp”),
rimraf = require(“rimraf”),
concat = require(“gulp-concat”),
cssmin = require(“gulp-cssmin”),
uglify = require(“gulp-uglify”),
replace = require(“gulp-replace”),
url = require(‘gulp-css-url’),
project = require(“./project.json”);
var paths = {
webroot: “./” + project.webroot + “/”
};
paths.js = paths.webroot + “js/**/*.js”;
paths.minJs = paths.webroot + “js/**/*.min.js”;
paths.css = paths.webroot + “css/**/*.css”;
paths.minCss = paths.webroot + “css/**/*.min.css”;
paths.concatJsDest = paths.webroot + “js/site.min.js”;
paths.concatCssDest = paths.webroot + “css/site.min.css”;
// Clean and JS commands are here
var cssFiles = [
paths.webroot + ‘assets/global/plugins/font-awesome/css/font-awesome.min.css’,
paths.webroot + ‘assets/global/plugins/bootstrap/css/bootstrap.min.css’,
paths.webroot + ‘assets/global/plugins/fancybox/source/jquery.fancybox.css’,
paths.webroot + ‘assets/global/plugins/carousel-owl-carousel/owl-carousel/owl.carousel.css’,
paths.webroot + ‘assets/global/plugins/uniform/css/uniform.default.css’,
paths.webroot + ‘assets/global/plugins/rateit/src/rateit.css’,
paths.webroot + ‘assets/global/plugins/jquery-ui/jquery-ui.min.css’,
paths.webroot + ‘assets/global/css/components.css’,
paths.webroot + ‘assets/frontend/layout/css/style.css’,
paths.webroot + ‘assets/frontend/pages/css/style-shop.css’,
paths.webroot + ‘assets/frontend/layout/css/style-responsive.css’,
paths.webroot + ‘assets/frontend/layout/css/themes/red.css’,
paths.webroot + ‘assets/frontend/layout/css/custom.css’
];
gulp.task(“min:css”, function () {
gulp.src(cssFiles)
.pipe(url({ mode: “absolute”, base: “.” }))
.pipe(replace(/wwwroot\\assets\\(.*)\)/gi,
function (x)
{
var ret = x.substring(8).replace(/\\/g, “/”);
return ret;
}))
.pipe(replace(‘/wwwroot/assets/’, ‘/assets/’))
.pipe(cssmin({ keepSpecialComments: 0, processImport: false }))
.pipe(concat(paths.concatCssDest))
.pipe(gulp.dest(“.”));
});
gulp.task(“min”, [“min:js”, “min:css”]);
NB! Additional packages used by my code must be also added to packages.json file in web application root.
I think we need something like this OOB with default ASP.NET 5 applications.