gulp-clean-css cannot set the right relative path for url() for assets such as fonts and images

2.8k views Asked by At

I use NPM and Gulp for my package manager and build system. I have installed "gulp-sass" to support sass, and "gulp-clean-css" so that I can @import css files inline. I capture my SCSS files in "_frontend/scss/**/*", and compiles that into a single file as "assets/frontend/css/styles.css". In the output location, I have other important resources folders that are siblings of "css": "fonts", "img", and "js".

My problem is I cannot get the url() relative paths to target correctly when I'm importing a "*.css" file. However, it is okay when I'm importing ".scss" files.

Here is my code (I took out sourcemaps, error log etc to simplify the question):

GULPFILE.JS

gulp.task('styles', function() {
    gulp.src(styles.src)
        .pipe(sassGlob())                                   // Support for bundle requires for Sass
        .pipe(cleanCSS({
            // relativeTo: './node_modules',    <-- I tried with different variations here, no luck
            // root: './node_modules',          <-- I tried with different variations here, no luck
            processImport: true
        }))
        .pipe(rename('styles.css'))                      // Name output CSS file
        .pipe(gulp.dest('../assets/frontend/css/'));
});

MAIN.SCSS

The following is OK

@import "font-awesome/scss/font-awesome.scss";

Output seems to come out with the correct relative paths Sample output: url(../fonts/FontAwesome/fontawesome-webfont.eot?v=4.6.1)

The following is NOT

@import '../node_modules/jquery-ui/themes/base/jquery-ui.css';

Sample output: url(../node_modules/jquery-ui/themes/base/images/animated-overlay.gif) ^^ The above somehow appends the "../node_modules". I want it to somehow set this to "../img/vendor/jquery-ui/what/ever/i/like/here"

Here's my directory structure.

_frontend    
 ├─fonts
 │  ├─Beamstyle-Icons
 │  └─Gotham-Light-Regular
 ├─node_modules
 │  ├─jquery-ui
 │  │  ├─scripts
 │  │  └─themes
 │  │      ├─base
 │  │         ├─images
 │  │         └─minified
 │  │             └─images
 │  └─ (other stuff...)
 │
 ├─scripts
 │  ├─app
 │  └─vendor
 └─scss
     ├─config
     ├─helpers
     │  ├─classes
     │  ├─functions
     │  ├─mixins
     │  └─placeholders
     └─src
         ├─blocks
         └─components
assets
 └─frontend
    ├─css
    ├─fonts
    ├─img
    │  ├─Beamstyle-Icons
    │  ├─FontAwesome
    │  └─Gotham-Light-Regular
    └─js

Would be great if anyone can help on this.

2

There are 2 answers

0
migli On

I made it work using relativeTo.

Doc says : (https://www.npmjs.com/package/clean-css)

relativeTo - path to resolve relative @import rules and URLs

It means that relativeTo + destination path must lead from gulpfile.js to the relative dir pointed by css assets (fonts, images).

Example :

\---project
    +---assets
    |   \---stylesheets
    |       |   style.css
    |       |   
    |       \---dist
    |               style.min.css
    | 
    |   \---fonts   
    |               my-font.ttf           
    \---gulp
            gulpfile.js

Destination path is set (from gulpfile) to '../assets/stylesheets/dist'

My task is :

// Create minified css
gulp.task('minifycss', function() {
    return gulp
        .src('../assets/stylesheets/*.css')
        .pipe(cleancss({relativeTo: '../assets/', compatibility: 'ie8'}))
        .pipe(rename({
            suffix: ".min"                              // add *.min suffix
        }))
        .pipe(gulp.dest('../assets/stylesheets/dist'))
});

output :

// style.css :
     src: url("../fonts/my-font.ttf");

// dist/style.min.css :
     src: url("../../fonts/my-font.ttf");
0
Mohammad Rafigh On

For version < 2.4

use relativeTo, root and target and if you don't want to rebase you can use rebase: false configuration options.

For version >= 2.4

gulp-clean-css has been upgraded to use clean-css 4.x so none of the options above work and they only provide rebaseTo option which will rebase all of your paths.