Source Maps for frontend Javascript

If you use Opbeat with your frontend Javascript app, you might have seen something like this on an error group

App settings

No pretty stack traces! No git annotations! No ponies!

Luckily, with the help of source maps, we can fix at least some of these issues. Source maps help us reconstruct the original source code from your compressed and transpiled Javascript that you send to browsers.

Basic requirements

Opbeat has these requirements for your source maps:

  • They need to be referenced in your compressed/transpiled Javascript, at the end of the file, like this:
    //# sourceMappingURL=./libs.min-599f6fba.js.map
    
  • The path needs to be relative to the js file.
  • The source map needs to be publicly available.

Additionally, we recommend that you use a cache-busting strategy to ensure that the URL to your Javascript and source map files changes every time its content changes. Please refer to the documentation of your asset pipeline for more information on this topic.

Generating source maps

Most asset pipelines like Gulp or Webpack either have built-in support for generating source maps, or have source map plugins. To get you started, here are some examples for the most common asset pipelines.

Gulp 3

You can generate source maps in Gulp 3 using the gulp-sourcemaps plugin.

In this example, we compress and concatenate all Javascript files in the src/assets/js folder (using the aptly named gulp-uglify and gulp-concat), and write the resulting Javascript file and its source map file to the build/js folder. Additionally, we use gulp-rev for cache-busting.

The task in your gulpfile.js should look somewhat like this.

var gulp = require('gulp');
var rev = require('gulp-rev');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var sourcemaps = require('gulp-sourcemaps');

gulp.task('scripts', function () {
    return gulp.src('src/assets/*.js')
        .pipe(sourcemaps.init())
        .pipe(concat('scripts.js'))
        .pipe(uglify())
        .pipe(rev())
        .pipe(sourcemaps.write('./maps'))
        .pipe(gulp.dest('build/js'));
})

Webpack

You can add source maps in Webpack using the devtool config option.

In this example we simply add devtool: 'source-map' to enable source map generation.

module.exports = {
    entry: './app.js',
    output: {
        path: __dirname,
        filename: 'dist/bundle.js'
    },
    devtool: 'source-map'
}