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)?

danwellman
  • 9,068
  • 8
  • 60
  • 88
serge
  • 13,940
  • 35
  • 121
  • 205

1 Answers1

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

ddprrt
  • 7,424
  • 3
  • 29
  • 25
  • 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?... – serge Sep 10 '15 at 14:28
  • 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 times – ddprrt Sep 10 '15 at 14:39
  • But I think that with sourcemaps, you won't have the need for two outputs anymore. ;-) – ddprrt Sep 10 '15 at 14:40
  • 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`? – serge Sep 10 '15 at 14:48
  • you should be fine with just one "out.map" – ddprrt Sep 10 '15 at 14:58
  • 1
    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. – Steven Ventimiglia Jan 25 '19 at 23:39
  • 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 https://github.com/gulp-sourcemaps/gulp-sourcemaps/wiki/Plugins-with-gulp-sourcemaps-support. – Per Quested Aronsson May 23 '19 at 07:12
  • thank you very much. This helped me debugging and fixing an issue I had :) – ggzone Oct 03 '19 at 12:46