mellis481
mellis481

Reputation: 4168

Handling image paths in css files when processed by gulp

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

Upvotes: 8

Views: 6124

Answers (2)

Jared Hooper
Jared Hooper

Reputation: 881

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'));
});

Upvotes: 1

Gina
Gina

Reputation: 580

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.

Upvotes: 0

Related Questions