Modify file in place (same dest) using Gulp.js and a globbing pattern

51,561

Solution 1

As you suspected, you are making this too complicated. The destination doesn't need to be dynamic as the globbed path is used for the dest as well. Simply pipe to the same base directory you're globbing the src from, in this case "sass":

gulp.src("sass/**/*.scss")
  .pipe(sass())
  .pipe(gulp.dest("sass"));

If your files do not have a common base and you need to pass an array of paths, this is no longer sufficient. In this case, you'd want to specify the base option.

var paths = [
  "sass/**/*.scss", 
  "vendor/sass/**/*.scss"
];
gulp.src(paths, {base: "./"})
  .pipe(sass())
  .pipe(gulp.dest("./"));

Solution 2

This is simpler than numbers1311407 has led on. You don't need to specify the destination folder at all, simply use .. Also, be sure to set the base directory.

gulp.src("sass/**/*.scss", { base: "./" })
    .pipe(sass())
    .pipe(gulp.dest("."));

Solution 3

gulp.src("sass/**/*.scss")
  .pipe(sass())
  .pipe(gulp.dest(function(file) {
    return file.base;
  }));

Originally answer given here: https://stackoverflow.com/a/29817916/3834540.

I know this thread is old but it still shows up as the first result on google so I thought I might as well post the link here.

Share:
51,561

Related videos on Youtube

Dan-Nolan
Author by

Dan-Nolan

Go from Zero Programming Experience to Blockchain Developer at ChainShot

Updated on July 11, 2022

Comments

  • Dan-Nolan
    Dan-Nolan almost 2 years

    I have a gulp task that is attempting to convert .scss files into .css files (using gulp-ruby-sass) and then place the resulting .css file into the same place it found the original file. The problem is, since I'm using a globbing pattern, I don't necessarily know where the original file is stored.

    In the code below I'm trying to use gulp-tap to tap into the stream and figure out the file path of the current file the stream was read from:

    gulp.task('convertSass', function() {
        var fileLocation = "";
        gulp.src("sass/**/*.scss")
            .pipe(sass())
            .pipe(tap(function(file,t){
                fileLocation = path.dirname(file.path);
                console.log(fileLocation);
            }))
            .pipe(gulp.dest(fileLocation));
    });
    

    Based on the output of the console.log(fileLocation), this code seems like it should work fine. However, the resulting CSS files seem to be placed one directory higher than I'm expecting. Where it should be project/sass/partials, the resulting file path is just project/partials.

    If there's a much simplier way of doing this, I would definitely appreciate that solution even more. Thanks!

  • Dan-Nolan
    Dan-Nolan about 10 years
    Ah, awesome. Thank you. Is there also an easy way to use a glob for the source, but just put everything straight up in the sass folder?
  • niftygrifty
    niftygrifty over 9 years
    This didn't work for me. I had to do gulp.src("dist/**/*") ... gulp.dest("./")
  • numbers1311407
    numbers1311407 about 9 years
    @Dan-Nolan one way of flattening the folder structure looks to be using gulp-rename, see this question
  • numbers1311407
    numbers1311407 about 9 years
    @niftygrifty According to the docs it should work in a normal situation. Files are written to their matching globbed path against a calculated relative base, in this case sass. Perhaps the sass plugin here is already modifying the paths?
  • Gui Ambros
    Gui Ambros almost 9 years
    This is the right answer. If you're trying to preserve the destination structure (i.e., not flatten the structure), you must indicate the base directory in gulp.src.
  • Mark
    Mark over 8 years
    But doesn't this save the file in /sass and not in the according subdirectory like /sass/any/where ? How do I make the files save in the globbed path?
  • Mark
    Mark over 8 years
    When I try this, the files are saved in "/" and not under the globbed path.
  • numbers1311407
    numbers1311407 over 8 years
    What @GuiAmbros says is not true, at least not according to the docs. The base, by default, is calculated to be everything before the globbed path. In my answer the base would be calculated to be ./sass,but the question specifies that the output retains the sass dir, which is why it's repeated in the dest. This answer achieves the same result using the base option, but neither approach is wrong.
  • numbers1311407
    numbers1311407 over 8 years
    It's also notable that the OP's situation is probably not that common, at least for CSS processing, as typically you'd expect to export into a css directory or similar, not from sass to sass. In such cases the accepted answer is actually simpler than this alternative.
  • numbers1311407
    numbers1311407 over 8 years
    @MonkeyKing gulp by default calculates the base as everything before the glob, then replicates the file structure of the glob when it writes. It won't flatten the structure. E.g. in this example sass/foo/bar.scss would be exported to sass/foo/bar.css. See the docs for more examples and the usage of options like base.
  • Mark
    Mark over 8 years
    @numbers1311407 in my case it does not work, what am I missing? Here is my complete task: gulp.task('theme-scripts-build', function () { return gulp.src([ 'app/View/Themed/**/*.js', '!app/View/Themed/**/bundle.theme.js' ], { base: "app/View/Themed" }) .pipe(plugins.stripDebug()) .pipe(plugins.concat('bundle.theme.js')) .pipe(plugins.uglify()) .pipe(gulp.dest('app/View/Themed')); }); I also tried variations like gulp.dest('app') and without setting the "base" option but the result is always the same: bundle.theme.js is saved in app/View/Themed/
  • numbers1311407
    numbers1311407 over 8 years
    I think you might be confused with how concat works. In the example for this question, each file matched by the glob is transformed and written out individually to a matching path at the destination dir. concat on the other hand is taking every file matched by the glob and writing them all to a single file, independent of any of the paths matched by the glob. You might want to break that into separate tasks per theme instead of globbing, or there may be a way to rewrite this so it works, but as is it doesn't really make sense and is probably outside the scope of this question.
  • numbers1311407
    numbers1311407 over 8 years
    In any case though, dest('wherever') should work to designate where the final file goes. I just put together a very simple testing situation using the concat plugin to make sure I'm not lying, and works just fine.
  • numbers1311407
    numbers1311407 over 8 years
    This thread is old but the answers are still correct, though I suppose this method is slightly DRYer (if slightly less efficient). The linked question, really, was an issue of using dest incorrectly. Sure the given solutions work, but doing it right the first time, simply replacing dest('./') with dest('./images'), would have achieved the same result.
  • bobbarebygg
    bobbarebygg over 8 years
    The reason the other solution did not work for me was that I had an array inside gulp.src() e.g. gulp.src(['sass/**', 'common/sass/**']) and when I searched for the answer, this was the post I found. Should probably have made that clearer though
  • numbers1311407
    numbers1311407 over 8 years
    Makes sense. In your case the problem is that there's no common base for gulp to calculate. Your solution works, but the solution given by @NightOwl888 of specifying the base would have worked as well. Updating the accepted answer to include the case of having no common base.
  • MrCroft
    MrCroft almost 6 years
    This should be the accepted answer! Not the other ones, which are specific to only one file or to a base path.