mode777 mode777 - 1 year ago 281
Javascript Question

Gulp: Generate sourcemaps for both minified and non-minified scripts

I'm new to gulp and have run into a problem which probably is a pretty common scenario. What I'm trying todo is compiling typescript into javascript, creating a sourcemap for it and then running uglify. I would like to have a sourcemap for the ugliyfied as well as the non uglified js.

What I'm trying to achive is the following file structure:

framework.js < this won't work

This is my gulp task:

var gulp = require('gulp'),
uglify = require('gulp-uglify')
ts = require("gulp-typescript")
sourcemaps = require('gulp-sourcemaps')
rename = require('gulp-rename');

var tsProject = ts.createProject("tsconfig.json");

gulp.task('typescript', function(){
.pipe(sourcemaps.write('.')) // Write sourcemap for non-minified version
.pipe(uglify()) // Code will fail here
.pipe(sourcemaps.write('.')) // Write sourcemap for minified version.

gulp.task('default', ['typescript']);

As you can see, I'm running sourcemaps.write() twice to get the two different files. This gives me an error

throw er; // Unhandled stream error in pipe.
^ GulpUglifyError: unable to minify JavaScript
at createError (C:\Users\alexa\Dropbox\code\Web\mhadmin\framework\node_modules\gulp-uglify\lib\create-error.js:6:14)

Leaving out the first one of the sourcemap.write() calls will result in a correct sourcemap for the minified version of the file.

Any ideas how to fix this?

EDIT: This is not exactly a duplicate of gulp: uglify and sourcemaps as I need to write multiple sourcemaps with multiple calls to gulp.dest()

Answer Source

The problem is that after the first .pipe(sourcemaps.write('.')) you have two files in your stream:


You write those two files to the file system (which is fine), but then you try to run uglify() on both of them. Since your file is not a JavaScript file and doesn't contain valid JavaScript code the uglify() plugin throws up.

After you have written to the file system there is really no reason to keep that file in the stream anymore. The vinyl file object for framework.js still has a .sourceMap property that carries all the transformations so far, meaning you can just remove the file from the stream.

The gulp-filter plugin let's you do just that:

var filter = require('gulp-filter');

gulp.task('typescript', function(){
  return tsProject.src()
   .pipe(filter('**/*.js')) // only let JavaScript files through here

After .pipe(filter('**/*.js')) only the framework.js file will be in the stream and uglify() won't throw up anymore.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download