gulp-terser icon indicating copy to clipboard operation
gulp-terser copied to clipboard

does not use pre-existing source map

Open youngderekm opened this issue 2 years ago • 3 comments

I am trying to use gulp-terser to run terser against js files that were compiled from TypeScript. The TypeScript compiler generated sourcemaps when it ran, and in this source map, "sources" lists my .ts file, as I would expect. When gulp-terser runs, however, it's as if the source map is generated from scratch. "sources" ends up listing the .js file instead of the original .ts file as expected.

Looking at the code, I don't see terser's sourceMap.content being set from chunk.sourceMap. Only sourceMap.filename is set. The terser doc says "The value of filename is only used to set file attribute (see the spec) in source map file.... If you're compressing compiled JavaScript and have a source map for it, you can use sourceMap.content".

Does this plugin support source maps that were previously loaded?

youngderekm avatar Dec 01 '21 19:12 youngderekm

How did you configure it? I just tested it, and the source map it generates restores the original ts code in the browser.

duan602728596 avatar Dec 02 '21 01:12 duan602728596

@duan602728596 Did you compile TS to JS then through Terser using Gulp? Would you mind sharing a sample Gulpfile that does this if you did?

From looking at the code, it really doesn't seem like the sourceMap.content property is supported at all. I kind of understand since it would need to also provide you some way to specify the input sourcemap that diverges from the Terser API. I expect it would need a function along the lines of:

function es(){
  return gulp.src('./src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(terser({
      sourceMap: {
        content: function(inputFilePath) {
          return inputFilePath + '.orig.map';
        }
      }
    }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./build'));
}

This is something like what gulp-sourcemaps does. I think it needs to be a function because you can't have a static input source map like if you were using it directly.

jeteon avatar Feb 11 '22 06:02 jeteon

@duan602728596 Did you compile TS to JS then through Terser using Gulp? Would you mind sharing a sample Gulpfile that does this if you did?

From looking at the code, it really doesn't seem like the sourceMap.content property is supported at all. I kind of understand since it would need to also provide you some way to specify the input sourcemap that diverges from the Terser API. I expect it would need a function along the lines of:

function es(){
  return gulp.src('./src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(terser({
      sourceMap: {
        content: function(inputFilePath) {
          return inputFilePath + '.orig.map';
        }
      }
    }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./build'));
}

This is something like what gulp-sourcemaps does. I think it needs to be a function because you can't have a static input source map like if you were using it directly.

Gulp's sourcemaps use vinyl-sourcemaps-apply. If you want to add sourcemaps, sourcemaps must have file attribute. So the sourceMap option of terser must configure filename. I can set terser's options as a function to suit your needs.

function es(){
  return gulp.src('./src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(terser(async function(opt) {
        return {
          sourceMap: {
            content: ''
          }
        }
    }))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('./build'));
}

But I still recommend that if you want to modify sourcemaps, you can use gulp-sourcemaps to modify.

duan602728596 avatar Feb 22 '22 03:02 duan602728596