Skip to content

[@sentry/nextjs] Webpack plugin uploads too much stuff #3769

Closed

Description

@lobsterkatie

This is an offshoot of vercel/next.js#26588, specifically this comment, regarding @sentry/nextjs 6.8.0.

TL;DR - We need to clean up our use of SentryWebpackPlugin such that

  • it doesn’t upload stuff it shouldn't, and
  • it doesn't upload the same stuff twice.

More specifically:

  • We shouldn't be uploading .css.map files.
  • We shouldn't be uploading the same file twice.
  • We (possibly? probably?) shouldn't be uploading HMR files.
  • We (possibly? probably?) shouldn't be uploading webpack files.
  • We may want to consider whether or not to upload nextjs, react, and other vendor files.

All of this can be fixed by changing our default webpack plugin ignore option, either for all builds (for the .css.map files, for example) or conditionally (to not upload client files during the server build, for example, which should prevent the duplication), but the question is what exactly it should be changed to.

Notes:

  • CSS map files

    I filed [sourcemaps] Exclude CSS maps if excluding CSS files sentry-cli#990 for a more long-term fix, but in the meantime we can just exclude them with the ignore option.

  • Duplicated files

    I think the easiest way to handle this is to have server and client builds each only upload their own files, as mentioned above. We'll need to experiment to make sure that we no files get missed this way.

  • HMR files (xyz.hot-update.js files in .next/static/webpack/)

    By default, the webpack plugin is in dryRun mode in dev (which is what produces HMR files), so this ought to be a moot point but a) people do all kinds of crazy things, and b) even when they don't, anyone using nextjs 10.x who runs yarn dev followed by yarn build will end up with HMR files because yarn build doesn't clear out .next before running (this is fixed in nextjs 11).

    I'm not sure exactly how hot-reloading works. Is there ever any circumstance in which we'd want to upload those files?

  • Webpack files (.next/server/webpack-runtime.js and .next/static/chunks/webpack-[hash].js)

    Again, not a webpack expert, but given that the SDK currently only works at runtime, is there any reason we'd need these?

  • Nextjs, React, and other vendor files (everything in .next/static/chunks that's not a page, and whichever .next/server/chunks/[num].js file has nextjs code rather than user code in it)

    Though there's some utility in being able to deminify third-party code, it may or may not be worth the time it takes to upload it. Perhaps this should be configurable? Also, is there any way to predict which of the .next/server/chunks/[num].js files is the one which contains nextjs code rather than user code? In my test app it's always 846.js, but I doubt that's always the case.

Activity

  1. kamilogorek commented on Jul 5, 2021

    @kamilogorek
    Contributor

    Repro code:

    // webpack.config.js
    
    const fs = require('fs');
    const SentryCliPlugin = require('@sentry/webpack-plugin');
    
    fs.rmdirSync('./dist', {recursive:true});
    
    const entry = Object.fromEntries(Array.from({ length: 1000 }, () => [`sentry${Math.floor(Math.random()*100000)}`, `./src/sentry.js`]));
    
    module.exports = {
      entry,
      output: {
        filename: '[name].js',
        path: __dirname + '/dist',
      },
      devtool: 'source-map',
      mode: 'development',
      plugins: [
        new SentryCliPlugin({
          include: 'dist',
          release: Date.now()
        }),
      ],
    };
    mkdir repro
    cd repro
    yarn init --yes
    yarn add webpack webpack-cli @sentry/webpack-plugin
    mkdir src
    curl https://browser.sentry-cdn.com/6.8.0/bundle.js > src/sentry.js
    vim .sentryclirc // place your token, org, project
    yarn webpack
    

    Repro results:

    [@DEBUG@] Start plugin 2021-07-05T11:00:38.382Z
    [@DEBUG@] Start upload 2021-07-05T11:01:19.754Z
    > Found 1990 release files
    > Analyzing 1990 sources
    > Rewriting sources
    > Adding source map references
    > Bundled 1990 files for upload
    > Uploaded release files to Sentry
    > File upload complete (processing pending on server)
    [@DEBUG@] Finish upload 2021-07-05T11:02:14.425Z
    [@DEBUG@] Finish plugin 2021-07-05T11:02:15.497Z
    Hash: 9ad26e07d9fe8ecc4a8e
    Version: webpack 4.46.0
    Time: 97056ms
    

    ~2000 artifacts, over 600MB in total. Total upload time ~55 sec. Total build time ~97sec.
    Gzipped bundle is ~120MB in total.

    image

  2. sokra commented on Jul 5, 2021

    @sokra
    • I'm not sure exactly how hot-reloading works. Is there ever any circumstance in which we'd want to upload those files?

    Assuming someone really want to run Sentry in development (explictly disabling dryRun). Error could happen in HMR update files too (since they will contain the new module code), so to have full source map coverage you probably have to upload them too. But this is an edge case. I would just do whatever is easier to implement.

  3. sokra commented on Jul 5, 2021

    @sokra
    • Webpack files (.next/server/webpack-runtime.js and .next/static/chunks/webpack-[hash].js)
      Again, not a webpack expert, but given that the SDK currently only works at runtime, is there any reason we'd need these?

    They are very small. I would include them.

    Best process files listed in compilation.getAssets(). There are also some flags in Asset.info you might find useful.

  4. sokra commented on Jul 5, 2021

    @sokra
    • Though there's some utility in being able to deminify third-party code, it may or may not be worth the time it takes to upload it.

    There is a framework chunk which contains only next.js and react vendor code. You could omit it, but you can't assume that it's always the same.

    In the end a mechnism which determines hashes of all files and ask the server which were uploaded before would cover that and other scenarios where many files where unchanged (which is often the case)

  5. lobsterkatie commented on Jul 5, 2021

    @lobsterkatie
    MemberAuthor

    I don't think you need server-related files.

    Best apply your plugin only to the client

    Hmmm - I'm not sure the logic here. If someone's using typescript, for example, they'll still need sourcemaps in order to show their original code in the stacktraces.

    Best process files listed in compilation.getAssets(). There are also some flags in Asset.info you might find useful.

    TIL. Will check those out, thanks.

    In the end a mechnism which determines hashes of all files and ask the server which were uploaded before would cover that and other scenarios where many files where unchanged (which is often the case)

    Because all uploaded files are scoped by release, in our current implementation of sourcemap processing it unfortunately doesn't matter whether or not a file's been uploaded with identical content before. In order to be used for demangling, it needs to be re-uploaded for each release. (Our assumption is that for the most part, users are only uploading their own code.)

  6. sokra commented on Jul 6, 2021

    @sokra

    I don't think you need server-related files.
    Best apply your plugin only to the client

    Hmmm - I'm not sure the logic here. If someone's using typescript, for example, they'll still need sourcemaps in order to show their original code in the stacktraces.

    Yep, I was wrong and you were very fast in reading the comment. I edited it shortly after. Sure, you will need sourcemaps for server code too.

  7. lobsterkatie commented on Jul 6, 2021

    @lobsterkatie
    MemberAuthor

    you were very fast in reading the comment

    LOL - one occasional upside of leaving a trail of open tabs in my wake and happening back upon them serendipitously, I guess? Just happened to happen back upon this one sooner than normal!

    In any case, great, glad we're on the same page. 🙂

  8. kamilogorek commented on Jul 6, 2021

    @kamilogorek
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions