8

I'm looking for a plugin chain to use with Gulp that provides:

  • source map support
  • less
  • minification
  • concatenation
  • URL replacement (rebase) to address relocation/concat

I currently have the first four, but I can't find a combination of existing plugins that will give me the last (URL rebasing) also. I've not found any URL rebasing plugins that emit sourcemaps.

Just to be clear, my issue is that when I compile multiple small CSS files from my project development folders, and output them into a common folder, the move resulting from concatenation breaks relative URLs, such as those for background images.

EDITS:

It sounds like the tool chain I currently use is already intended to solve this problem. So, that's ostensibly the answer. However, that raises another question, how the required syntax is supposed to work.

That question theoretically has lots of duplicates out there:

Unfortunately no answers actually explain the syntax, they just demonstrate voodoo; so I don't know why the following isn't working. If I can get it resolved I'll come back here and flag this accepted to indicate this tool chain does actually do what I need.

The source files:

/assets
    /site
        styleInput1.less "url(../site/logo.png)"
        logo.png
        background.png
    /application
        styleInput2.less "url(../site/background.png)"

The gulp task:

gulp.task(filename, function () {
    return gulp.src(files)
        .pipe(sourcemaps.init())
        .pipe(less())
        .pipe(minifyCss({ relativeTo: './compiled' }))
        .pipe(concat(filename))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('./compiled'));
});

The output, with broken URLs. Note the multiple defects. Although the CSS is raised a directory level relative to the required assets, an additional parent directory has been added (!). Also, one of the URLs has had a hard asset folder name changed (!). Very strange:

/compiled
    styleOutput1.css "url(../../compiled/logo.png)"
    styleOutput2.css "url(../../site/background.png)"

My apologies for continuing the voodoo, but here is my working gulp pipe:

.pipe(minifyCss({ relativeTo: './compiled', target: './compiled' }))

And the correct output:

/compiled
    styleOutput1.css "url(../assets/site/logo.png)"
    styleOutput2.css "url(../assets/site/background.png)"
Community
  • 1
  • 1
shannon
  • 8,664
  • 5
  • 44
  • 74

1 Answers1

6

I personally use gulp-minify-css and specify the relativeTo attribute.

gulp.task('css', function() {
    gulp.src('./assets/css/main.css')
// Here I specify the relative path to my files
      .pipe(minifyCSS({keepSpecialComments: 0, relativeTo: './assets/css/', processImport: true}))
      .pipe(autoprefixer({
        browsers: ['last 2 versions'],
        cascade: false
      }))
      .pipe(gulp.dest('./assets/css/dist/'))
      .pipe(notify({
          "title": "Should I Go?",
          "subtitle": "Gulp Process",
          "message": '<%= file.relative %> was successfully minified!',
          "sound": "Pop",
          "onLast": true
      }));
  });

If that doesn't work for you, they have a lot of other parameters to rebase URLs : https://github.com/jakubpawlowicz/clean-css#how-to-use-clean-css-programmatically

Notably:

  • rebase - set to false to skip URL rebasing
  • relativeTo - path to resolve relative @import rules and URLs
  • restructuring - set to false to disable restructuring in advanced optimizations
  • root - path to resolve absolute @import rules and rebase relative URLs
Romain Braun
  • 3,624
  • 4
  • 23
  • 46
  • That's great, I'm already using `gulp-minify-css`! I didn't realize it had that feature, but I'm trying it out now. – shannon May 20 '15 at 02:56
  • That's funny, I see now its core is `clean-css`, and I was looking for a plugin that was based on that tool for this reason. – shannon May 20 '15 at 03:00
  • ugh, none of these gulp path relationship configuration commands are ever explained clearly. `relativeTo` isn't doing what I expect, and I also don't understand from the docs how it is different from `root` and `target`. – shannon May 20 '15 at 03:18
  • 2
    Yes, but I have no idea why it works. I had to use 2 parameters. As far as I can tell, for most circumstances, the output folder should be specified for the `relativeTo`, `target`, and `root` parameters. The documentation is clear that `target` is for relative URLs, `root` is for absolute URLs, and `relativeTo` somehow interacts with both of the former. But it doesn't explain how. See my OP edits for information on my fix. – shannon May 20 '15 at 17:10
  • after some headache and some tinkering, I think `relativeTo` is the path of your source css file and `target` is the intended path of your cleaned css file. Like @shannon, I need to use both `relativeTo` and `target`. I haven't played with `root` but I think it's meant to be the original root of urls before clean-css processing. – lastoneisbearfood Jun 22 '15 at 07:32
  • 1
    Thanks @RomainBraun spent hours trying to figure out what was happening to my URLs `rebase: false` worked perfectly. – Thomas Taylor Nov 29 '15 at 02:13