gulp-sourcemaps: sourceRoot doesn't work for files in sub folders

I have stored my source files in a number of sub folders.

It looks like the sourceRoot parameter doesn’t correctly handle those files. It doesn’t consider the relative part beginning at the sources’ root up to their actual location when creating the source map entry.

sourcemaps
Please refer to this issue for reference:

https://github.com/Microsoft/vscode/issues/4705

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 13
  • Comments: 16

Most upvoted comments

I agree that the sourceRoot option does not work as expected when assigning a string value and source files are located in sub directories.

Here’s a workaround using the path util:

const path = require('path');
// ...
sourceRoot: (file) => {
    return path.join(path.relative(path.join(outputDir, path.dirname(file.relative)), '.'), sourceDir);
}

Hi I’ve got same issue Thanks @ckiely91. Your solution was very helpful. Here is my full task for “Node.js targeted” TS. Hope it would be useful…

gulp.task('build', () => {
  const project = ts.createProject('tsconfig.json');
  return gulp.src('./app/**/*.ts')
    .pipe(sourcemaps.init())
    .pipe(ts(project))
    .js
    .pipe(sourcemaps.write('./', {
      includeContent: false,
      sourceRoot: file => `${'../'.repeat(file.relative.split(/^win/.test(process.platform) ? '\\' : '/').length)}app`
    }))
    .pipe(gulp.dest('./dist'));
});

I found following code in sources of plugin

    if (typeof options.sourceRoot === 'function') {
      sourceMap.sourceRoot = options.sourceRoot(file);
    } else {
      sourceMap.sourceRoot = options.sourceRoot;
    }

Looks like sourceMap passed to output as is without, resolution of extra ../

Well, I had lots of trouble, trying to find the right combination to make it work. In the end I found a simple expression that worked for any combination of subdirectories, depth or relative location between the source and build directories:

const writeSourceMapsOptions = {
  sourceRoot: (file) => {
    return path.posix.relative(path.posix.dirname(file.relative), "");
  },
};

and then just pass it to .pipe(gulpSourceMaps.write(writeSourceMapsOptions)).

This works for both Istambul reports and the Node debugger.

For whatever reason updating the sourceRoot as above didn’t work for me so I updated the mapSources directly. Thanks to everyone for leading me to this!

mapSources: function(sourcePath, file) { let relativeLocation = path.join(path.relative(path.join(outputDir, path.dirname(file.relative)), ‘.’), ‘src/’); let relativeLocationToFile = path.join(relativeLocation, sourcePath); return relativeLocationToFile; }}))

@zhakhalov, found that you can actually just use path.sep instead of /^win/.test(process.platform) ? '\\' : '/' to make it platform independent.