Opbeat is joining forces with Elastic – Read our blog post

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:

  • Make sure your source maps are referenced in your compressed/transpiled Javascript file like this:
    //# sourceMappingURL=./libs.min-599f6fba.js.map
    
  • 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'
}

Troubleshooting

Source map availability

To test if source maps are available for a specific frame you can try this:

curl http://MYDOMAIN.com/assets/my-production-file.min.js | grep sourceMappingURL

Check to see if the reference to the sourcemap is in the output. If you see a sourceMappingURL, try downloading it:

curl -s -I -X GET http://MYDOMAIN.com/assets/<sourceMappingURL>

These two steps are what our servers do for each frame in the stacktrace when we receive an error from your app.