1

var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('sass', function () {
    return gulp.src(['./project/**/*.scss', '!./project/**/_*/'])
        .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest(function (file) {
            return file.base;
        }));
});
/project  
    --> Module1  
        --> scss  
            --> Test1.scss  
    --> Module2  
        --> scss 
            --> Test2.scss 

Click here for folder structure

enter image description here

I have a project with multiple modules. I'm trying to write a gulp task that compiles the sass files and creates css files within each module. I have the following folder structure and gulpfile.

The task is currently designed to compile the scss files and create the css and css.map files in the same location as the scss files.
How can I move them both outside the scss folder, but still inside their respective modules?

A.A Noman
  • 5,244
  • 9
  • 24
  • 46
Vai Wood
  • 13
  • 4

2 Answers2

0

You can add a config file to specify the build location for the files so that they can be generated in a folder of your choice, like so:

let gulp = require('gulp');
let sass = require('gulp-sass');
let sourcemaps = require('gulp-sourcemaps');
let rename = require('gulp-rename');
let gulpUtil = require('gulp-util');
let merge = require('merge-stream');

const CONFIGS = [require('./gulp.module1.config'), require('./gulp.module2.config')];

gulp.task('sass', function () {
    let tasks = CONFIGS.map(config => {
        return gulp.src(config.sass.src)
            .pipe(sass())
            .on('error', error => console.log(error))
            .pipe(rename('app.min.css'))
            .pipe(gulp.dest(config.buildLocations.css));
    });

    return merge(tasks);
});

Config 1:

module.exports = {
    app: { baseName: 'module1' },
    sass: {
        src: ['./project/module1/scss/*.scss']
    },
    buildLocations: {
        css: './project/module1/'
    }
}

config 2

module.exports = {
    app: { baseName: 'module1' },
    sass: {
        src: ['./project/module2/scss/*.scss']
    },
    buildLocations: {
        css: './project/module2/'
    }
}

Folder Structure

UPDATE: If you don't want to write an individual config file you can use the path library to rename it, leaves you with the files on the parent level.

gulp.task('sass', function () {
return gulp.src('./project/**/scss/*.scss')
        .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(sourcemaps.write('.'))
        .pipe(rename(function(file) {
            file.dirname = path.dirname(file.dirname)
            return file;
        }))
        .pipe(gulp.dest('./project'))
});
  • 1
    Also see my answer at https://stackoverflow.com/questions/48544503/switch-output-folder-based-on-filename-in-gulp-task/48553076#48553076 If possible the gulp-flatten version is really nice. – Mark Feb 10 '18 at 03:02
0

gulp-flatten is really handy for selecting which directories to include or exclude from the final structure.

var gulp = require('gulp');
var sass = require('gulp-sass');
var sourcemaps = require('gulp-sourcemaps');

var flatten = require("gulp-flatten");

gulp.task('sass', function () {
    return gulp.src(['./project/**/*.scss', '!./project/**/_*/'])
        .pipe(sourcemaps.init())
        .pipe(sass().on('error', sass.logError))
        .pipe(sourcemaps.write('.'))

        // keep one parent directory: "Module1", "Module2"
        // relative to your glob bae, so first after "project"

         .pipe(flatten({ includeParents: 1}))

        .pipe(gulp.dest('project'));
});
Mark
  • 143,421
  • 24
  • 428
  • 436