Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rewrite urls of images in vendor CSS files using Grunt

I am trying to move frontend dependencies out of the version control system. A combination of Bower.io and Grunt should be able to do this.

A problem however occurs that I am yet unable to solve with bundling multiple vendor libraries. For example assume I have the following directory structure where the components directory is the directory that Bower.io saves the dependencies in:

├── assets └── components     ├── bootstrap     │   ├── img     │   │   └── glyhs.gif     │   └── less     │       └── bootstrap.css     └── jquery-ui         ├── css         │   └── style.css         └── images             ├── next.gif             └── prev.gif 

Now assume I want to bundle both jQuery's style.css and Bootstrap' bootstrap.css. I will save this bundled file in assets/bundled.css.

However in this file the references to the original images (../images/next.gif and ../img/glyhs.gif) are incorrect. They will have to be rewritten in order to work (so ../images/next.gif => ../components/jquery-ui/images/next.gif). I believe(d) this rewriting of URLs is something Grunt should be able to do. But I can not seem to get this to work using the cssmin/less/copy tasks. For example the following Grunt setup (only moving 1 file) fails to work:

module.exports = function (grunt) {     grunt.initConfig({         pkg: grunt.file.readJSON('package.json'),         less: {             options: {                 compile: false,                 relativeUrls: true             },             bootstrap: {                 src: 'components/bootstrap/less/bootstrap.less',                 dest: 'assets/bootstrap.css'             }         }     });     grunt.loadNpmTasks('grunt-contrib-less');     grunt.registerTask('dist-css', ['less']); }; 

Either:

  • Have I misconfigured Grunt or done something wrong?

  • Or is the workflow I am describing simply not the right one and should I use another one instead.

Thanks!

like image 464
Roel van Duijnhoven Avatar asked Aug 15 '13 13:08

Roel van Duijnhoven


1 Answers

You probably wat to take a look at this grunt package https://github.com/Ideame/grunt-css-urls. This package seems to be intended to solve exactly your problem.

Edit: after looking at this plugin I didn't like the idea of rewriting my markup in order to make my build process smoother. So I ended up writing my own tiny function which does the rewrite for me.

I use grunt's concat plugin for bundling my css files. Good thing about this plugin is that it suports file processing function before concatenation. Now my gruntfile looks like this:

grunt.initConfig({ concat: {     options: {     separator: '\n',     process: function (src, filepath) {         var cssPatt = new RegExp('app(\/.*\/).*\.css$');          //filter out everithing except css files         var file = cssPatt.exec(filepath);          if (file) {             var urlPatt = /url\(\'(.*)\'\)/g;          console.log('In file: ' + filepath);          //replace every url(...) with its absolute path         return src.replace(urlPatt, function (match, p1) {             console.log(' * ' + match + ' -> ' + 'url(\'' + file[1] + p1 + '\')');             return 'url(\'' + file[1] + p1 + '\')';         });         }          return src;     }     }, } 
like image 97
Ulan Murzatayev Avatar answered Oct 23 '22 06:10

Ulan Murzatayev