Handling image paths in css files when processed by gulp
Asked Answered
I

2

8

Previously in my MVC apps, I've used .NET to optimize (concatenate, minify, etc.) my CSS files. I've had to use custom transform classes to handle paths in my CSS like:

.brand {
    background-image: url("../images/logo.png");
}

or even:

.brand {
    background-image: url("/Content/images/logo.png");
}

I've added gulp to my most recent project for front-end testing and I thought I'd also use it to automatically optimize my CSS and JS files. Here is my gulp task to process CSS files:

var gulp = require('gulp');
var concat = require('gulp-concat');
var cssmin = require('gulp-minify-css');
var rename = require("gulp-rename");
var less = require('gulp-less');
var uglify = require('gulp-uglify');

gulp.task('styles', function () {
    return gulp.src('./Content/custom/site.less')
        .pipe(less())
        .pipe(gulp.dest('./dist/css'))
        .pipe(cssmin())
        .pipe(rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest('./dist/css'));
});

The CSS file is minified, uglified, etc. successfully, but links to images, for example, are incorrect. Relative paths of course now reference something like http://localhost/site-folder/dist/css/Content/images/logo. Paths that were originally something like /Content/images/logo.png end up being http://localhost/Content/images/logo.png, but unfortunately, they don't account for domain folders which my site has.

Any ideas?

Thanks in advance

Inna answered 16/7, 2015 at 13:52 Comment(1)
Also, are you using partial files or not? I'm unfamiliar with the gulp-less api, but with gulp-sass you must specify which directory contains partial files and that WILL effect the background images path.Ligneous
S
1

The simplest way would be to use gulp-replace in a pipe for your css, and replace your current urls with the new image address. (I also added gulp-load-plugins to reduce require() bloat.

This assumes you're migrating the images as well in a separate task.

var gulp = require('gulp'),
    plugins = require('gulp-load-plugins'); // replaces all your requires

var yourDirectory = "/Content/images/";

gulp.task('styles', function () {
    return gulp.src('./Content/custom/site.less')
        .pipe(plugins.less())
        .pipe(gulp.dest('./dist/css'))
        .pipe(plugins.replace('url("../images/', 'url("' + yourDirectory)
        .pipe(plugins.cssmin())
        .pipe(plugins.rename({
            suffix: '.min'
        }))
        .pipe(gulp.dest('./dist/css'));
});
Serafina answered 1/7, 2016 at 14:0 Comment(0)
L
0

Usually what I end up doing is creating a /dest, /public or /build directory that is separate from my source. That way in my preprocessor files I can just say images/img.png and never worry about the correct path because I know gulp will be dumping images in the build directory always.

I also like this style, because it forces me to think securely about what files I'm going to expose to the user and can configure my web server to only serve static from there (avoiding path traversal, etc [See also: if you use Express, see express.static()]). Another good benefit to this is you can have a separate gulp task for compressing images or making sprites which is great for performance. While you don't need a setup as advanced as this one, I recommend browsing gulp-starter https://github.com/vigetlabs/gulp-starter (looking specifically at how they do their Sass piping and image compressing steps).

If that solution isn't right for your project, you could get the path from your process. In Node this is easy with __dirname or path.cwd()... but I think that's probably a worse idea.

Ligneous answered 18/11, 2015 at 1:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.