gulp: uglify and sourcemaps
Asked Answered
G

1

54

I am using gulp.

I would like to having one or multiple JS files (say jQuery) to combine them in one, minify it, and write it to a distribution folder.

This is how I do it:

minifyJS(['/js/myModule.file1.js',
          '/js/myModule.file2.js'], '/dist/js', 'myModule')

the function:

function minifyJS(sourceFiles, destinationFolder, filenameRoot) {
    return gulp.src(sourceFiles)
        .pipe(plumber())

        // .pipe(sourcemaps.init()) here ???
        .pipe(concat(filenameRoot + '.js'))
        .pipe(sourcemaps.init()) // or here ???

        .pipe(gulp.dest(destinationFolder)) // save .js
        .pipe(uglify({ preserveComments: 'license' }))
        .pipe(rename({ extname: '.min.js' }))
        .pipe(gulp.dest(destinationFolder)) // save .min.js
        .pipe(sourcemaps.write('maps'))
        .pipe(gulp.dest(destinationFolder)) // save .map
}

What I am not sure about is the sourcemaps.init() location...

Should I create multiple (2 in my case) map files (that would be nice if is supported by browsers) or only one (/maps/myModule.map)?

Garton answered 10/9, 2015 at 13:2 Comment(0)
M
115

So this is how sourcemaps work in Gulp: Each element you select via gulp.src gets transferred into a virtual file object, consisting of the contents in a Buffer, as well as the original file name. Those are piped through your stream, where the contents get transformed.

If you add sourcemaps, you add one more property to those virtual file objects, namely the sourcemap. With each transformation, the sourcemap gets also transformed. So, if you initialize the sourcemaps after concat and before uglify, the sourcemaps stores the transformations from that particular step. The sourcemap "thinks" that the original files are the output from concat, and the only transformation step that took place is the uglify step. So when you open them in your browser, nothing will match.

It's better that you place sourcemaps directly after globbing, and save them directly before saving your results. Gulp sourcemaps will interpolate between transformations, so that you keep track of every change that happened. The original source files will be the ones you selected, and the sourcemap will track back to those origins.

This is your stream:

 return gulp.src(sourceFiles)
    .pipe(sourcemaps.init())
    .pipe(plumber())
    .pipe(concat(filenameRoot + '.js'))
    .pipe(gulp.dest(destinationFolder)) // save .js
    .pipe(uglify({ preserveComments: 'license' }))
    .pipe(rename({ extname: '.min.js' }))
    .pipe(sourcemaps.write('maps'))
    .pipe(gulp.dest(destinationFolder)) // save .min.js

sourcemaps.write does not actually write sourcemaps, it just tells Gulp to materialize them into a physical file when you call gulp.dest.

The very same sourcemap plugin will be included in Gulp 4 natively: http://fettblog.eu/gulp-4-sourcemaps/ -- If you want to have more details on how sourcemaps work internally with Gulp, they are in Chapter 6 of my Gulp book: http://www.manning.com/baumgartner

Megaron answered 10/9, 2015 at 14:7 Comment(8)
Thanks a lot for this detailed and helpful explanation... Now how about the fact that there is x (2) files in input and only one in output? Should I generate one or multiple sourcemaps to include in the distribution folder along with the mymodule.min.js file?...Garton
Gulp will create the correct mapping for you there. If you just have one output file, and also only one sourcemap, the sourcemap will understand the origins and show you two files in the dev tools. If you want to have sourcemaps for your two outputs (the normal and the minfied one), just call sourcemaps.write two timesMegaron
But I think that with sourcemaps, you won't have the need for two outputs anymore. ;-)Megaron
I mean I have in1.js and in2.js (2) and one out.(min.)js... is there possible (has sense) to have in1.map and in2.map or just one out.map?Garton
you should be fine with just one "out.map"Megaron
This answer - including your codeblock - resolved a year-old issue I had with mapping; which was the log referring to individual JS files properly, instead the single uglified script.min.js. Being self-taught, it's really appreciated. Thank you.Darkness
Is there any way to work around plugins in the chain that don't support the sourcemaps plugin, and still generate a valid sourcemap? For example, I can't find gulp-strip-debug in the list at github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/….Mendelian
thank you very much. This helped me debugging and fixing an issue I had :)Egor

© 2022 - 2024 — McMap. All rights reserved.