Next.js: Production Source Maps

Created on 7 May 2017  路  27Comments  路  Source: vercel/next.js

Is it possible to generate/serve separate source map files in production?

Most helpful comment

Can we reopen this issue? @arunoda

There is a valid use-case for having production source maps. Or at-least built as part of production code build. But we can strip before it is served.

  1. The files that are bundled in webpack output are different depending on if you are in development or production.
  2. Uploading .map files to sites like Rollbar, Airbrake, or Honeybadger is a common practice.

Currently we can achieve the follow -

  • External Sourcemap on Development only
  • Inline Sourcemap on Production only

We want to generate external source maps, but do not seem to have the capabilties with next.config.js to override the default npm run build settings.

Some help would be beneficial. Regardless what we do, the source maps are ignored within a production deploy of Next.

All 27 comments

Looks like https://github.com/zeit/next.js/issues/918#issuecomment-275922407 is an answer to your question?

Thanks @albinekb that's it is.
But @Rowno exposing source maps into production is not a pretty good idea.

I tried this config and ran NODE_ENV=production next build but no .map files were output.

module.exports = {
  webpack: config => {
    config.devtool = 'source-map'

    for (const r of config.module.rules) {
      if (r.loader === 'babel-loader') {
        r.options.sourceMaps = true
      }
    }

    return config
  }
}

Source maps in production make tools like Sentry far more useful.

@Rowno we use inline-source-maps usually.
I've less experience on source-maps.
But anyway, I don't recommend exposing them for production.
But you can always tinker with the webpack config and what's going on and configure it.

What's so bad about exposing them in production?

You should upload them as a release to sentry instead @Rowno
See https://docs.sentry.io/clients/javascript/sourcemaps/#uploading-source-maps-to-sentry for more 馃憣

I would if I could generate them. 馃槄 Looks like there's multiple things preventing them from working including Uglify.

Can we reopen this issue? @arunoda

There is a valid use-case for having production source maps. Or at-least built as part of production code build. But we can strip before it is served.

  1. The files that are bundled in webpack output are different depending on if you are in development or production.
  2. Uploading .map files to sites like Rollbar, Airbrake, or Honeybadger is a common practice.

Currently we can achieve the follow -

  • External Sourcemap on Development only
  • Inline Sourcemap on Production only

We want to generate external source maps, but do not seem to have the capabilties with next.config.js to override the default npm run build settings.

Some help would be beneficial. Regardless what we do, the source maps are ignored within a production deploy of Next.

Want to point out that we should do the following -

https://webpack.js.org/configuration/devtool/

hidden-source-map. This generates the external file but does not create the link to the file. This is exactly what needs to be supported.

This is really important for me too.

Different users are going to want different kinds of sourcemaps (e.g., I actually don't want mine to be hidden鈥擨'm not trying to obfuscate my code, and a linked sourcemap is by far the simplest way to get the file to Sentry), so I think a configuration option that lets the user provide a function returning the type of sourcemap to generate would be good. The default in Next could be something like:

({dev}) => dev ? 'inline-source-map' : 'false'

And a user who wants production source maps could just do:

({dev}) => dev ? 'inline-source-map' : 'source-map' // or 'hidden-source-map'

@ethanresnick - Mostly agree. This is what we found out when we experimented.

  1. Full source maps added enough to our download, that Google Page Speed insights lowered our score by 10 pts for desktop and mobile. Hence why hidden-source-map was the option we are recommending.

  2. "simplest way to get the file to Sentry" - totally understand what your going through. We can get sourcemaps to Rollbar a lot easier by having them on the site. Turns out because of 1 above, we didn't feel this was a good idea. So as part of our CI pipeline we end up building them, then throwing them away and doing a normal build.

  3. next.config.js does not have all the power over sourcemaps. Any changes we besides below make work well development, but fail with production builds. Looking at the source code, we decided to go a different route. The following snippet builds inline-sourcemaps only.

const webpack = require('webpack');

module.exports = {
  webpack: (config) => {
    if (!process.env.SOURCE_MAPS) {
      return config;
    }

    const configOptions = config;
    configOptions.devtool = 'source-map';
    configOptions.output.sourceMapFilename = '[file].map';

    // Perform customizations to config existing plugins
    for (const options of configOptions.plugins) {
      if (options instanceof webpack.optimize.UglifyJsPlugin) {
        options.sourceMap = true;
        break;
      }
    }

    return configOptions;
  },
};

We set the above up so it exits the custom config if we don't have SOURCE_MAPS set. This will generate inline-sourcemaps in production. We then wrote a custom script using:

npm install convert-source-maps --save-dev
npm install combine-source-maps --save-dev

Long story, we would scrape all JS files in ./next and ./next/bundles/pages for any inline sourcemaps, and pull them out. We then use convert & combine to create external files for the sourcemaps. Then we would upload to our Error Reporting suite.

We called all this code through a new and special NPM build command. Once it was done, we removed the .next/ folder and did a normal build to prepare for our deploy. We also "saved" build-stats.json & BUILD_ID to use for the second build, so everything would line up.

Long story short, this was a incredible amount of effort, and a total hack. Without changing how next handles production builds, this was the best option we had.

I've gotten configurable production source maps working by making some changes to the next.js server and build process. I still have some tidy up to do but I'm hoping to submit a pull request in the next week or so.

Here's my work in progress: https://github.com/zeit/next.js/compare/v3-beta...Rowno:production-source-maps

@rowno - some feedback - can you make it hidden-source-maps.

This does the same thing as source-maps, except it does not create a reference within the app.js file or page/ files.

This means your user will not download it, but you have it generated to uploaded to Sentry like @albinekb said above. My team uses Rollbar, and would greatly benefit from this.

Additionally, @arunoda - if we put a pull request in for this (GJ @Rowno), can we get this on the 2.4.x branch? My team can not switch over to 3.0.0 beta with our live site yet. We need to wait for that set of tags to stabilize. But we need sourcemaps ASAP.

We had a hack in to make them sort of work. But the 2.4.1 release broke that effort. We did not go as far as @Rowno to modify next itself.

You can set it to whatever you want, I made it a config option. But the browser will only download external source maps if you have the DevTools open, so source-map should be fine.

So is there clean way of generating separate production source maps ( for Sentry ) in next 3 ?

+1 we're trying to upload the sourcemap to bugsnag on build and can't seem to do it with the webpack config customization that's made available now. As is, production errors are impossible to debug. @Rowno's work seems promising, but we're hesitant to switch to our own fork and integrate his changes into the most recent next version.

Hey there. Same here, would really like to have an official feature or a good example to have source maps working in prod for tools like Sentry.

Any solutions for this issue?

@arunoda Why exposing source-maps in production is a bad idea? I would like to know reasons. For example in webpack documentation they say:

We encourage you to have source maps enabled in production, as they are useful for debugging as well as running benchmark tests.

If you're using sentry, I've had good experiences w/ this webpack plugin on create-react-app, though i've yet to implement it in a nextjs project:
https://github.com/40thieves/webpack-sentry-plugin

@isBatak @Tomekmularczyk
It seems to be on the roadmap for next 5

Next 5 does add source maps.

If you are using Heroku I forked a existing Sentry Souremap Buildpack to work with the .next folder structure.

You can find it here - https://github.com/WebGrind/buildpack-sentry-sourcemaps

The instructions are very easy. Enable source maps. Add config variables. Add build pack. Will take you all of 5 minutes to setup.

for Next 5.1+
Additional configuration is required.
This code generates main.js.map.

Next.js (version 5.1+)

// next.config.js

module.exports = {
  webpack(config, { dev }) {
    config.devtool = 'source-map';
    for (const options of config.plugins) {
      if (options['constructor']['name'] === 'UglifyJsPlugin') {
        options.options.sourceMap = true;
        break;
      }
    }

    return config;
  },
};

FYI: https://github.com/zeit/next.js/pull/3793#issue-168946327
https://github.com/axsann/buildpack-sentry-sourcemaps/blob/master/README.md#nextjs-version-51

FYI the plugin has changed so that now you have to call it twice as in the readme:

const withSourceMaps = require('@zeit/next-source-maps')()
module.exports = withSourceMaps({
  webpack(config, options) {
    return config
  }
})

Caught me out until I saw that new extra call, because it silently fails otherwise

that extra () really caught me off-guard! 馃槀

not having source maps in staging and production is very un-intuitive and counter-productive when debugging :(

Was this page helpful?
0 / 5 - 0 ratings