6

I'm trying to create a gulp task to compress and create a source map at the same time. The compression and source map creation works, but I can't seem how to figure out how to get the output names right when using the gulp-rename plugin.

To simplify: I have a source.js file in the /src folder and I want to create both the .min.js and .js.map file in the /dist folder.

Here's what I have:

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

// compressed
gulp.src(['src/*.js'])
    .pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))        
    .pipe(uglify())        
    .pipe(sourcemaps.write('./', {
        sourceMappingURL: function(file) {
            return file.relative + '.map';
        }
    }))
    .pipe(rename({ suffix: '.min' }))
    .pipe(gulp.dest('./dist'));
});

This works in that it creates the following in /dist:

  • jquery-resizable.min.js (all good - compressed, map ref and right name)
  • jquery-resizable.js.min.map (map is there, but name is bad - should be jquery-resizable.js.map)

I've tried a ton of variations but I can't figure out how to get the map and compression to build and get the correct file names.

I also tried renaming the files in a separate step, but due to the async nature of gulp, that doesn't work reliably - sometimes it works sometimes it doesn't so that doesn't seem like an option either.

What am I missing?

I'm not married to creating the sourcemaps in just this way, but what is the proper way to do this? All the examples I've seen seem to do what I do above, except they don't rename the output file to min.js which seems like an important part of the process.

bdukes
  • 152,002
  • 23
  • 148
  • 175
Rick Strahl
  • 17,302
  • 14
  • 89
  • 134

2 Answers2

4

I would suggest using gulp-filter to remove the .map files from the pipeline during the rename.

var jsFilter = require('gulp-filter')([ '*.js', ], { restore: true, });
gulp.src(['src/*.js'])
    .pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))        
    .pipe(uglify())        
    .pipe(sourcemaps.write('./', {
        sourceMappingURL: function(file) {
            return file.relative + '.map';
        }
    }))
    .pipe(jsFilter)
    .pipe(rename({ suffix: '.min' }))
    .pipe(jsFilter.restore)
    .pipe(gulp.dest('./dist'));

That said, our workflow does the rename before the sourcemaps and it generates the maps correctly.

gulp.src(['src/*.js'])
    .pipe(sourcemaps.init())        
    .pipe(uglify())        
    .pipe(rename({ suffix: '.min', }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('./dist'));
bdukes
  • 152,002
  • 23
  • 148
  • 175
  • Thanks @bdukes. The first example using jsfilter works, but - not particularily happy that it takes an additional plug-in and such non-readable syntax to get such common simple thing done. Thanks though - this will at least work and remove my extra `fix` task. The second example doesn't work for me - it still produces `jquery-resizable.min.js.map` for me. I see in some threads around gulp-rename that it's supposed to be aware of the source maps plug-in but it just doesn't seem to do the right thing. Either way - there should be a simpler and more natural expressive way to get this done. – Rick Strahl Dec 22 '15 at 00:27
  • In my second example, it produces the `.map` file with `.min` in the name, but that matches the declaration in the `.min.js` file, so it all works. Are you concerned about the naming because it doesn't work, or for aesthetic reasons? – bdukes Dec 22 '15 at 15:09
  • Also, consider running `npm outdated` to see if some of your plugins need to be updated. – bdukes Dec 22 '15 at 15:10
1

@bdukes answer mostly solved my problem and led me to the right solution. I'm posting the actual solution that worked for me in the specific case I mentioned above which is based on his answer.

One of my issues was related to not being able to generate the raw sources files along with the compressed and map files. I was able to make it work with an extra step explicitly moving the files in a separate .pipe(gulp.dest('./dist')) operation:

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

    // compress and source map
    gulp.src(['src/*.js'])
        .pipe(sourcemaps.init({ includeContent: false, sourceRoot: './' }))
        .pipe(uglify())   
        .pipe(sourcemaps.write('.', {
            sourceMappingURL: function(file) {
                return file.relative + '.map';
            }
        }))        
        .pipe(jsFilter)
        .pipe(rename({ suffix: '.min' }))
        .pipe(jsFilter.restore)
        .pipe(gulp.dest('./'));

    // also copy source files
    gulp.src(['src/*.js'])
        .pipe(gulp.dest('./dist'));
});

Moral of the story - don't overthink things - I was trying to get it all to work in one operation.

Rick Strahl
  • 17,302
  • 14
  • 89
  • 134