50

I have the following in my gulpfile.js:

   var sass_paths = [
        './httpdocs-site1/media/sass/**/*.scss',
        './httpdocs-site2/media/sass/**/*.scss',
        './httpdocs-site3/media/sass/**/*.scss'
    ];

gulp.task('sass', function() {
    return gulp.src(sass_paths)
        .pipe(sass({errLogToConsole: true}))
        .pipe(autoprefixer('last 4 version'))
        .pipe(minifyCSS({keepBreaks:true}))
        .pipe(rename({ suffix: '.min'}))
        .pipe(gulp.dest(???));
});

I'm wanting to output my minified css files to the following paths:

./httpdocs-site1/media/css
./httpdocs-site2/media/css
./httpdocs-site3/media/css

Am I misunderstanding how to use sources/destinations? Or am I trying to accomplish too much in a single task?

Edit: Updated output paths to corresponding site directories.

Everett Green
  • 632
  • 3
  • 8
David Angel
  • 1,001
  • 2
  • 10
  • 21

9 Answers9

64

I guess that the running tasks per folder recipe may help.

Update

Following the ideas in the recipe, and oversimplifying your sample just to give the idea, this can be a solution:

var gulp = require('gulp'),
    path = require('path'),
    merge = require('merge-stream');

var folders = ['httpdocs-site1', 'httpdocs-site2', 'httpdocs-site3'];

gulp.task('default', function(){

    var tasks = folders.map(function(element){
        return gulp.src(element + '/media/sass/**/*.scss', {base: element + '/media/sass'})
            // ... other steps ...
            .pipe(gulp.dest(element + '/media/css'));
    });

    return merge(tasks);
});
Ghidello
  • 1,863
  • 20
  • 21
15

you are going to want to use merge streams if you would like to use multiple srcs but you can have multiple destinations inside of the same one. Here is an example.

var merge = require('merge-stream');


gulp.task('sass', function() {
   var firstPath = gulp.src(sass_paths[0])
               .pipe(sass({errLogToConsole: true}))
               .pipe(autoprefixer('last 4 version'))
               .pipe(minifyCSS({keepBreaks:true}))
               .pipe(rename({ suffix: '.min'}))
               .pipe(gulp.dest('./httpdocs-site1/media/css'))
               .pipe(gulp.dest('./httpdocs-site2/media/css'));
   var secondPath = gulp.src(sass_paths[1])
               .pipe(sass({errLogToConsole: true}))
               .pipe(autoprefixer('last 4 version'))
               .pipe(minifyCSS({keepBreaks:true}))
               .pipe(rename({ suffix: '.min'}))
               .pipe(gulp.dest('./httpdocs-site1/media/css'))
               .pipe(gulp.dest('./httpdocs-site2/media/css'));
   return merge(firstPath, secondPath);
});

I assumed you wanted different paths piped here so there is site1 and site2, but you can do this to as many places as needed. Also you can specify a dest prior to any of the steps if, for example, you wanted to have one dest that had the .min file and one that didn't.

ckross01
  • 1,681
  • 2
  • 17
  • 26
  • 2
    This solution just seems like it has a lot of repetition. Is there a better way? – David Angel Nov 06 '14 at 17:46
  • are your pipes are the same for all files? – ckross01 Nov 06 '14 at 18:04
  • 3
    @DavidAngel remember, it's just JavaScript. You can refactor the repetition out to a function that returns the stream, and just have your task call that function and combine the results. Sidebar: I prefer [`gulp-util`](https://github.com/gulpjs/gulp-util) for that stuff. – Evan Davis Nov 06 '14 at 18:29
  • use [streamqueue](https://stackoverflow.com/a/26098747/2518317) instead if the order of the stuff going through these streams is important – Hashbrown Jul 10 '19 at 11:21
6

You can use gulp-rename to modify where files will be written.

gulp.task('sass', function() {
    return gulp.src(sass_paths, { base: '.' })
        .pipe(sass({errLogToConsole: true}))
        .pipe(autoprefixer('last 4 version'))
        .pipe(minifyCSS({keepBreaks:true}))
        .pipe(rename(function(path) {
            path.dirname = path.dirname.replace('/sass', '/css');
            path.extname = '.min.css';
        }))
        .pipe(gulp.dest('.'));
});

Important bit: use base option in gulp.src.

Heikki
  • 15,329
  • 2
  • 54
  • 49
4

For the ones that ask themselves how can they deal with common/specifics css files (works the same for scripts), here is a possible output to tackle this problem :

var gulp = require('gulp');
var concat = require('gulp-concat');
var css = require('gulp-clean-css');

var sheets = [
    { src : 'public/css/home/*', name : 'home.min', dest : 'public/css/compressed' },
    { src : 'public/css/about/*', name : 'about.min', dest : 'public/css/compressed' }
];

var common = {
    'materialize' : 'public/assets/materialize/css/materialize.css'
};

gulp.task('css', function() {
    sheets.map(function(file) {
        return gulp.src([
            common.materialize, 
            file.src + '.css', 
            file.src + '.scss', 
            file.src + '.less'
        ])
        .pipe( concat(file.name + '.css') )
        .pipe( css() )
        .pipe( gulp.dest(file.dest) )
    }); 
});

All you have to do now is to add your sheets as the object notation is constructed.

If you have additionnal commons scripts, you can map them by name on the object common, then add them after materialize for this example, but before the file.src + '.css' as you may want to override the common files with your customs files.

Note that in the src attribute you can also put path like this :

'public/css/**/*.css'

to scope an entire descendence.

Anwar
  • 4,162
  • 4
  • 41
  • 62
3

I had success without needing anything extra, a solution very similar to Anwar Nairi's

const p = {
  dashboard: {
    css: {
      orig: ['public/dashboard/scss/style.scss', 'public/dashboard/styles/*.css'],
      dest: 'public/dashboard/css/',
    },
  },
  public: {
    css: {
      orig: ['public/styles/custom.scss', 'public/styles/*.css'],
      dest: 'public/css/',
    },
    js: {
      orig: ['public/javascript/*.js'],
      dest: 'public/js/',
    },
  },
};

gulp.task('default', function(done) {
  Object.keys(p).forEach(val => {
    // 'val' will go two rounds, as 'dashboard' and as 'public'
    return gulp
      .src(p[val].css.orig)
      .pipe(sourcemaps.init())
      .pipe(sass())
      .pipe(autoPrefixer())
      .pipe(cssComb())
      .pipe(cmq({ log: true }))
      .pipe(concat('main.css'))
      .pipe(cleanCss())
      .pipe(sourcemaps.write())
      .pipe(gulp.dest(p[val].css.dest))
      .pipe(reload({ stream: true }));
  });
  done(); // <-- to avoid async problems using gulp 4
});
Neithan Max
  • 11,004
  • 5
  • 40
  • 58
3

Multiple sources with multiple destinations on gulp without using any extra plugins just doing concatenation on each js and css. Below code works for me. Please try it out.

 const gulp = require('gulp');
 const concat = require('gulp-concat');
 function task(done) {
    var theme = {
        minifiedCss: {
             common: { 
                src : ['./app/css/**/*.min.css', '!./app/css/semantic.min.css'], 
                name : 'minified-bundle.css', 
                dest : './web/bundles/css/' 
            }
        },
        themeCss:{
            common: { 
                 src : ['./app/css/style.css', './app/css/responsive.css'], 
                 name : 'theme-bundle.css', 
                 dest : './web/bundles/css/' 
            }
        },
        themeJs: {
            common: {
                src: ['./app/js/jquery-2.1.1.js', './app/js/bootstrap.js'],
                name: 'theme-bundle.js',
                dest: './web/_themes/js/'
            }
        }
    }
    Object.keys(theme).map(function(key, index) {
        return gulp.src(theme[key].common.src)
        .pipe( concat(theme[key].common.name) )
        .pipe(gulp.dest(theme[key].common.dest));
    });
    done();
}
exports.task = task;
0

Using gulp-if helps me a lot.

The gulp-if first argument. is the gulp-match second argument condition

gulp-if can be found in gulp-if

import {task, src, dest} from 'gulp';
import VinylFile = require("vinyl");
const gulpif = require('gulp-if');

src(['foo/*/**/*.md', 'bar/*.md'])
    .pipe(gulpif((file: VinylFile) => /foo\/$/.test(file.base), dest('dist/docs/overview')))
    .pipe(gulpif((file: VinylFile) => /bar\/$/.test(file.base), dest('dist/docs/guides')))
});
Exil
  • 311
  • 2
  • 11
  • 26
xsilen T
  • 1,515
  • 14
  • 10
0

I think we should create 1 temporary folder for containing all these files. Then gulp.src point to this folder

Hai Bui
  • 303
  • 1
  • 2
  • 9
-1

The destination will have the same directory structure as the source.

Anushil Kumar
  • 674
  • 8
  • 8