Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Production Source Maps #1903

Closed
Rowno opened this issue May 7, 2017 · 32 comments · Fixed by #3578
Closed

Production Source Maps #1903

Rowno opened this issue May 7, 2017 · 32 comments · Fixed by #3578

Comments

@Rowno
Copy link
Contributor

Rowno commented May 7, 2017

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

@albinekb
Copy link
Contributor

albinekb commented May 7, 2017

Looks like #918 (comment) is an answer to your question?

@arunoda
Copy link
Contributor

arunoda commented May 7, 2017

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

@arunoda arunoda closed this as completed May 7, 2017
@Rowno
Copy link
Contributor Author

Rowno commented May 7, 2017

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.

@arunoda
Copy link
Contributor

arunoda commented May 7, 2017

@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.

@Rowno
Copy link
Contributor Author

Rowno commented May 7, 2017

What's so bad about exposing them in production?

@albinekb
Copy link
Contributor

albinekb commented May 8, 2017

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 👌

@Rowno
Copy link
Contributor Author

Rowno commented May 8, 2017

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

@khrome83
Copy link
Contributor

khrome83 commented May 11, 2017

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.

@khrome83
Copy link
Contributor

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.

@ethanresnick
Copy link

ethanresnick commented May 21, 2017

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—I'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'

@khrome83
Copy link
Contributor

khrome83 commented May 21, 2017

@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.

@Rowno
Copy link
Contributor Author

Rowno commented Jun 8, 2017

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: v3-beta...Rowno:production-source-maps

@khrome83
Copy link
Contributor

khrome83 commented Jun 8, 2017

@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.

@Rowno
Copy link
Contributor Author

Rowno commented Jun 8, 2017

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.

@ilionic
Copy link

ilionic commented Sep 12, 2017

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

@marbemac
Copy link

+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.

@gmaliandi
Copy link

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.

@isBatak
Copy link

isBatak commented Nov 26, 2017

Any solutions for this issue?

@Tomekmularczyk
Copy link
Contributor

@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.

@brandonmp
Copy link
Contributor

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

@BentoumiTech
Copy link

BentoumiTech commented Nov 29, 2017

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

@khrome83
Copy link
Contributor

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.

@axsann
Copy link

axsann commented Apr 10, 2018

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: #3793 (comment)
https://github.com/axsann/buildpack-sentry-sourcemaps/blob/master/README.md#nextjs-version-51

@notatestuser
Copy link
Contributor

for Next 5.1+
https://github.com/zeit/next-plugins/tree/master/packages/next-source-maps

@notatestuser
Copy link
Contributor

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

@stoikerty
Copy link
Contributor

that extra () really caught me off-guard! 😂

@hems
Copy link

hems commented Apr 10, 2020

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

@loganfsmyth
Copy link
Contributor

Anyone here have success with this for cases like Sentry? I see productionBrowserSourceMaps exists now, but https://github.com/vercel/next.js/blob/0af3b526408bae26d6b3f8cab75c4229998bf7cb/docs/advanced-features/source-maps.md says they'll be publicly served, which is not what I'd want.

I guess I can rm -rf .next/**/*.map after the build is done and they've been uploaded, but seems like an easy way to leak the original code if something goes wrong or changes in Next.

@karianpour
Copy link

karianpour commented May 2, 2021

@loganfsmyth did you have a chance to remove the source map after build. I need to build them to upload to sentry server, but after that I do not want them on my public server. ( I use @sentry/nextjs ) and I have build script like next build && rm -rf .next/**/*.map but it did not work.

Edit: On Heroku, I could make it work by next build && find ./.next -name \"*.map\" -delete

@abeauchemin-planned
Copy link

@loganfsmyth @karianpour found any solution about this? I'm also trying to find a way to get the sourcemap in sentry but not served during deployment

@Nmaxime
Copy link

Nmaxime commented Jan 17, 2022

@loganfsmyth @karianpour @abeauchemin-planned , have you found a solution ?
I have the same use case.

@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Feb 17, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.