Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a Gulp Task to do minification and source maps to a .min file properly

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.

like image 518
Rick Strahl Avatar asked Sep 25 '22 21:09

Rick Strahl


2 Answers

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'));
like image 165
bdukes Avatar answered Oct 17 '22 01:10

bdukes


@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.

like image 33
Rick Strahl Avatar answered Oct 17 '22 02:10

Rick Strahl