bugsnag / webpack-bugsnag-plugins

Webpack plugins for common BugSnag actions.
MIT License
32 stars 29 forks source link

Next.js project Cannot determine "minifiedUrl" argument for bugsnag-sourcemaps #3

Closed sabrinaluohk01 closed 5 years ago

sabrinaluohk01 commented 6 years ago

Hello :) bugsnag requires the publicPath, but in nextjs generated project, the public path is always with chunkhash, but the file is under .next/bundle.

So when I upload the sourcemap under ./next/bundle, it wont work with the caught error in minified production code.

is there any other way to fix this issue? thanks!

website:

image

error in bugsnag

image

uploaded source map

image

bengourley commented 6 years ago

Hi @sabrinaluohk01! Sorry to see that you're having issues.

I went to put together a small next.js example at to play around with things, and I had to fix a few issues with this library (#4). I've published that as v1.1.1.

Unfortunately that won't solve the issues you're having, though. The problem stems from the fact that the next bundles are not served with the same paths that they exist with on the filesystem…

The next router does this – mapping paths like /_next/xxxxxxxxxxxxxxx/page/index.js onto /.next/bundles/pages/index.js. In order to support this kind of dynamic serving we'd need to add a feature to this library. At the moment we just join the publicPath with the location of the bundle on disk…

https://github.com/bugsnag/webpack-bugsnag-plugins/blob/07ffe2a62b91dd96571d75ce16fae9475a4e3a27/source-map-uploader-plugin.js#L54-L58

… assuming that the result of a webpack build is served from the filesystem statically – as it usually is.

Until we get around to supporting your use case, may I suggest an alternative. Rather than uploading sourcemaps to Bugsnag, you should leave the //# sourceMappingURL=index.js.map annotations in your JS, and allow Bugsnag's servers to retrieve the source map when we process an error. If your application isn't publicly available, you'll need to whitelist our IPs.

N.B. you should also add this config if you haven't already, to ensure source maps are created for all of your JS.

azizhk commented 6 years ago

Hey @bengourley, thanks for the help. What do you suggest to upload server sourcemaps?

webpack(config, { dev, isServer }) {
  if (!dev) {
    config.devtool = 'source-map'

    const appVersion = gitRev.short()
    const BUGSNAG_API = isServer
      ? dotenv.parsed.BUGSNAG_API_SERVER
      : dotenv.parsed.BUGSNAG_API_CLIENT

    config.plugins.push(
      new BugsnagBuildReporterPlugin(
        {
          apiKey: BUGSNAG_API,
          appVersion: appVersion,
          releaseStage: dotenv.parsed.BUGSNAG_ENV
        }
      )
    )
    config.plugins.push(
      new BugsnagSourceMapUploaderPlugin({
        apiKey: BUGSNAG_API,
        appVersion: appVersion,
        releaseStage: dotenv.parsed.BUGSNAG_ENV
      })
    )
  }
}

I started with something like this but came accross this issue. So now if I can upload only server side sourcemaps, that would be enough. I'll figure something else and comment for client side.

bengourley commented 6 years ago

@azizhk we don't currently support source maps for server-side javascript – however we do plan to support it soon.

azizhk commented 6 years ago

Hey, so here's my script to upload client side sourcemaps after a build. Works with next.js v6. Does not work with next.js v7. Thought would share.

const fs = require('fs')
const _ = require('lodash')
const { resolve } = require('path')
const { promisify } = require('util')
const { upload: _uploadToBugsnag } = require('bugsnag-sourcemaps')
const { config: loadEnv } = require('dotenv')
const { short: gitRevShort } = require('git-rev-sync')

loadEnv({
  path: resolve(__dirname, '../.env')
})

const readFile = promisify(fs.readFile)
const uploadToBugsnag = promisify(_uploadToBugsnag)
const DASHBOARD_URL = process.env.DASHBOARD_URL

module.exports = async function uploadClientSourcemapTask(): Promise<void> {
  if (!process.env.BUGSNAG_API_CLIENT) {
    return
  }
  const BUILD_ID = await readFile(
    resolve(__dirname, '../.next/BUILD_ID'),
    'utf8'
  )
  const manifest = JSON.parse(
    await readFile(resolve(__dirname, '../.next/build-manifest.json'), 'utf8')
  )

  const baseConfig = {
    apiKey: process.env.BUGSNAG_API_CLIENT,
    appVersion: gitRevShort(),
    overwrite: true,
    uploadSources: true
  }

  const pageBundles = Object.keys(manifest)
    .filter(p => p.startsWith('bundles/pages'))
    .map(p => p.replace(/^bundles\/pages\//, ''))
  await Promise.all(
    pageBundles.map(p =>
      uploadToBugsnag({
        ...baseConfig,
        minifiedUrl: `${DASHBOARD_URL}_next/${BUILD_ID}/page/${p}`,
        minifiedFile: resolve(__dirname, `../.next/bundles/pages/${p}`),
        sourceMap: resolve(__dirname, `../.next/bundles/pages/${p}.map`)
      })
    )
  )

  const chunkBundles = _.entries(manifest).filter(([k, _]) =>
    k.startsWith('chunks')
  )

  await Promise.all(
    chunkBundles.map(([_, v]) =>
      uploadToBugsnag({
        ...baseConfig,
        minifiedUrl: `${DASHBOARD_URL}_next/webpack/${v[0]}`,
        minifiedFile: resolve(__dirname, `../.next/${v[0]}`),
        sourceMap: resolve(__dirname, `../.next/${v[0]}.map`)
      })
    )
  )

  await uploadToBugsnag({
    ...baseConfig,
    minifiedUrl: `${DASHBOARD_URL}_next/${manifest['main.js']}`,
    minifiedFile: resolve(__dirname, `../.next/${manifest['main.js']}`),
    sourceMap: resolve(__dirname, `../.next/${manifest['main.js']}.map`)
  })
}

Upgrading to next 7 soon, will share if successful.

azizhk commented 6 years ago

With Next 7, this plugin works as is and does not need much modifications. As next now stores the files in the same path that their served to the client.

Just you need to turn on sourcemaps. For that you can use @zeit/next-source-maps

next.config.js:

const withSourceMaps = require('@zeit/next-source-maps')()
module.exports = withSourceMaps({
  webpack(config, options) {
    const { dev, isServer, defaultLoaders } = options
    if (!dev && !isServer) {
      config.plugins.push(
        new BugsnagSourceMapUploaderPlugin({
          apiKey: BUGSNAG_API_KEY, // replace this
          publicPath: `http*://*.example.com/_next/` // replace this
        })
      )
    }
  }
})

Above code is for @zeit/next-source-maps version "0.0.4-canary.0" You should be able to close this issue now.

bnisbett commented 5 years ago

@bengourley Follow up question from earlier in the thread. Is there now support for source maps for server-side javascript?

isBatak commented 5 years ago

@bengourley could we reopen this issue? I think we need a way to define a wildcard in place of next BUILD_ID. For example minifiedUrl like this one: https://example.com/_next/static/L0eJ6XV0Hw9IEdAUlJFh5/pages/example.js should be: https://example.com/_next/static/*/pages/example.js I'm thinking to add an additional transformSource option to plugin setting that will allow transforming of a source string, e.g. static/L0eJ6XV0Hw9IEdAUlJFh5/pages/example.js to static/*/pages/example.js.

snmaynard commented 5 years ago

@bnisbett yes we support server side source maps now! You should upload your source maps -> https://docs.bugsnag.com/platforms/javascript/source-maps/#source-map-upload

azizhk commented 5 years ago

So here is my next.config.js to upload client and server sourcemaps. Next.js version 8 @zeit/next-source-maps version 0.0.4-canary.1

const fp = require("lodash/fp");

const enhance = fp.compose(
  require("@zeit/next-source-maps")({ devtool: "hidden-source-map" }),
  // Add other plugins here
);

module.exports = enhance({
  webpack(config, { isServer, dev }) {
    if (isServer) {
      config.devtool = "source-map";
    }

    const BUGSNAG_API = isServer
      ? BUGSNAG_API_SERVER_KEY // replace here
      : BUGSNAG_API_CLIENT_KEY; // replace here
    if (!dev) {
      const { BugsnagSourceMapUploaderPlugin } = require("webpack-bugsnag-plugins");

      config.plugins.push(
        new BugsnagSourceMapUploaderPlugin({
          apiKey: BUGSNAG_API,
          overwrite: true,
          releaseStage: "production",
          publicPath: isServer
            ? ".next/server/"
            : "*/_next/"
        })
      );
    }

    return config;
  }
});
lifeiscontent commented 5 years ago

@bengourley do you think you could share how to integrate this into nextjs? the example doesn't talk about how to get sourcemaps working.

mattdyoung commented 5 years ago

@azizhk @lifeiscontent Our docs describe how to get source maps applied to any js project.

This can be done using either our bugsnag-sourcemaps tool: https://docs.bugsnag.com/build-integrations/js/#uploading-source-maps

or using our webpack plugin: https://docs.bugsnag.com/build-integrations/webpack/#uploading-source-maps

Our FAQs cover the common reasons why source maps may not be applied: https://docs.bugsnag.com/api/js-source-map-upload/#frequently-asked-questions

If you're still having issues getting this to work can you contact support@bugsnag.com or raise a support request via the Bugsnag dashboard with details of which Bugsnag project this relates to? We can then take a look at your account / project and help to diagnose the reason.

azizhk commented 5 years ago

My solution above works for me. @lifeiscontent can you mention your next.js version and I can point you accordingly.

dcalhoun commented 5 years ago

@lifeiscontent the following is my config for Next 7 that successfully loads source maps to Bugsnag. It is based off the work @azizhk already shared.

const {
  bugsnagApiKeyServer,
  bugsnagApiKeyClient,
} = require("./env-config.js");
const {
  BugsnagBuildReporterPlugin,
  BugsnagSourceMapUploaderPlugin
} = require("webpack-bugsnag-plugins");

const DEPLOY_ENV = process.env.DEPLOY_ENV || "development";

module.exports = {
  serverRuntimeConfig: { bugsnagApiKey: bugsnagApiKeyServer },
  publicRuntimeConfig: { bugsnagApiKey: bugsnagApiKeyClient },
  webpack: (config, { buildId, isServer }) => {
    if (DEPLOY_ENV !== "development") {
      config.plugins.push(
        new BugsnagBuildReporterPlugin({
          apiKey: isServer ? bugsnagApiKeyServer : bugsnagApiKeyClient,
          appVersion: buildId,
          releaseStage: DEPLOY_ENV,
          sourceControl: {
            provider: "<PROVIDER_NAME>",
            repository: "<PROVIDER_URL>",
            revision: "$Format:%H$"
          }
        })
      );

      config.plugins.push(
        new BugsnagSourceMapUploaderPlugin({
          apiKey: isServer ? bugsnagApiKeyServer : bugsnagApiKeyClient,
          appVersion: buildId,
          overwrite: true,
          publicPath: isServer ? ".next/server" : `<DOMAIN>/_next/`
        })
      );
    }

    return config;
  }
};
lifeiscontent commented 5 years ago

@azizhk here's my config that is currently not working

const fs = require('fs');
const path = require('path');
const withSass = require('@zeit/next-sass');
const withSourceMaps = require('@zeit/next-source-maps');
const {
  BugsnagBuildReporterPlugin,
  BugsnagSourceMapUploaderPlugin,
} = require('webpack-bugsnag-plugins');

const RELEASE_STAGE = process.env.RELEASE_STAGE || 'development';

function getRevision() {
  if (fs.existsSync('.git')) {
    const rev = fs
      .readFileSync('.git/HEAD')
      .toString()
      .trim()
      .split(/.*[: ]/)
      .slice(-1)[0];
    if (rev.indexOf('/') === -1) {
      return rev;
    } else {
      return fs
        .readFileSync(`.git/${rev}`)
        .toString()
        .trim();
    }
  }
}

module.exports = withSourceMaps(
  withSass({
    publicRuntimeConfig: {
      BUGSNAG_API_KEY: process.env.BUGSNAG_BROWSER_API_KEY,
    },
    serverRuntimeConfig: {
      BUGSNAG_API_KEY: process.env.BUGSNAG_SERVER_API_KEY,
    },
    sassLoaderOptions: {
      includePaths: ['styles', 'node_modules'].map(d =>
        path.join(__dirname, d)
      ),
      sourceMap: true,
    },
    cssLoaderOptions: {
      sourceMap: true,
    },
    webpack(config, { buildId, isServer }) {
      if (RELEASE_STAGE !== 'development') {
        config.plugins.push(
          new BugsnagBuildReporterPlugin({
            apiKey: isServer
              ? process.env.BUGSNAG_SERVER_API_KEY
              : process.env.BUGSNAG_BROWSER_API_KEY,
            appVersion: process.env.HEROKU_RELEASE_VERSION || buildId,
            releaseStage: RELEASE_STAGE,
            notifyReleaseStages: ['staging', 'production'],
            sourceControl: {
              provider: 'github',
              repository: 'https://github.com/redacted/redacted',
              revision: getRevision(),
            },
          })
        );

        config.plugins.push(
          new BugsnagSourceMapUploaderPlugin({
            apiKey: isServer
              ? process.env.BUGSNAG_SERVER_API_KEY
              : process.env.BUGSNAG_BROWSER_API_KEY,
            appVersion: process.env.HEROKU_RELEASE_VERSION || buildId,
            overwrite: true,
            publicPath: isServer ? '.next/server' : '*/_next/',
            releaseStage: RELEASE_STAGE,
            notifyReleaseStages: ['staging', 'production'],
          })
        );
      }
      return config;
    },
  })
);
azizhk commented 5 years ago

Can you share the version of next.js that you are using?

mattdyoung commented 5 years ago

Hi @lifeiscontent

Thanks for raising the related support request. As mentioned on the response, looking at your account I can see that your uploaded source maps have an app version specified but the error reports we're receiving from your application don't, so setting the appVersion when initializing Bugsnag in your application should resolve this.

lifeiscontent commented 5 years ago

@azizhk I'm using next 8 and it seems source maps are not being uploaded on the browser end of things

@mattdyoung do I need to map over the outputs in webpack with the plugin? it seems to only be uploading the server js source maps.

mattdyoung commented 5 years ago

This ended up being resolved under a Bugsnag support request.

For anyone else with this issue, it looks to be an issue with Next, but we've found a workaround.

You would need to apply this package: https://github.com/zeit/next-plugins/tree/master/packages/next-source-maps but you'll need the latest pre-release version: @zeit/next-source-maps@0.0.4-canary.1

Next doesn't output source maps by default. This plugin enables source map generation, but with versions before this one it had a bug where it didn't output for browser, only for Node.js. Here's the related issue: https://github.com/zeit/next-plugins/issues/377#issuecomment-513604330

VadymBoguslavsky commented 5 years ago

Is someone still here?)

I have an issue with this. I loaded my sourcemaps

Screen Shot 2019-09-12 at 3 43 42 PM

to bugsnag but when i tried to start my server locally with now dev is seems that something went wrong:

Preparing next.config.js for build: [BugsnagSourceMapUploaderPlugin] uploading sourcemap for "*/static/runtime/webpack.js"

It just keep spinning forever. Can someone tell what is going on?

const path = require('path');
const webpack = require('webpack')
const withSass = require('@zeit/next-sass');
const {
  WebpackBundleSizeAnalyzerPlugin
} = require('webpack-bundle-size-analyzer');
const { ANALYZE_SIZE } = process.env;
const {
  BugsnagBuildReporterPlugin,
  BugsnagSourceMapUploaderPlugin
} = require("webpack-bugsnag-plugins");
const withSourceMaps = require('@zeit/next-source-maps')

const withBundleAnalyzer = require("@next/bundle-analyzer")({
  enabled: process.env.ANALYZE === 'true',
});

const globalSass = [
  path.resolve(__dirname, 'styles/_mixins.scss'),
  path.resolve(__dirname, 'styles/_variables.scss'),
  path.resolve(__dirname, 'styles/_functions.scss'),
  path.resolve(__dirname, 'styles/_placeholders.scss')
]

module.exports = withBundleAnalyzer(withSass(withSourceMaps({
  sassLoaderOptions: {
    includePaths: ['public/assets/styles']
  },
  webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
    config.module.rules.push({
      enforce: "pre",
      test: /\.scss$/,
      loader: "sass-resources-loader",
      options: {
        resources: globalSass
      }
    });
    config.plugins.push(
      new webpack.IgnorePlugin(/^encoding$/, /node-fetch/)
    );
    if (ANALYZE_SIZE) {
      config.plugins.push(new WebpackBundleSizeAnalyzerPlugin('stats.txt'))
    }

    config.plugins.push(
      new BugsnagSourceMapUploaderPlugin({
        apiKey: '********',
        appVersion: buildId,
        publicPath: '*/',
        override: true,
        uploadSource: true,
      })
    );

    return config
  }
})));

module.exports.target = 'serverless'
azizhk commented 5 years ago

You just need to add an if condition to add BugsnagSourceMapUploaderPlugin in production mode.

  if (!dev) {
    config.plugins.push(
      new BugsnagSourceMapUploaderPlugin({
        apiKey: '********',
        appVersion: buildId,
        publicPath: '*/',
        override: true,
        uploadSource: true,
      })
    );
  }
VadymBoguslavsky commented 5 years ago

Oh my, thank you)

But i have another question) It seems that my source maps is ignored for now

Screen_Shot_2019-09-12_at_5_14_02_PM

What can i do about this?

azizhk commented 5 years ago

Do you set appVersion as the buildId when initializing bugsnag client? https://github.com/bugsnag/webpack-bugsnag-plugins/issues/3#issuecomment-512822605

(Even after setting appVersion, you will see sourcemaps only for new errors)

VadymBoguslavsky commented 5 years ago

You mean here?

import React from 'react';
import bugsnag from '@bugsnag/js';
import bugsnagReact from '@bugsnag/plugin-react';

const bugsnagClient = bugsnag({
  apiKey: 'd0a59e8349ee3e1ba609cdbd2ecaecc5',
  notifyReleaseStages: ['production', 'staging'],
  appVersion: '1.0.0'  <---- is this it?
});

bugsnagClient.use(bugsnagReact, React);

export default bugsnagClient;

as I understand it buildId and this version must be the same, but how to know buildID?

azizhk commented 5 years ago
if (typeof window !== "undefined" && window.__NEXT_DATA__ && window.__NEXT_DATA__.buildId) {
  const bugsnagClient = bugsnag({
    apiKey: 'd0a59e8349ee3e1ba609cdbd2ecaecc5',
    notifyReleaseStages: ['production', 'staging'],
    appVersion: window.__NEXT_DATA__.buildId
  });
}

You should initialize this in browser. Similarly on the server also you would get global.__NEXT_DATA__.buildId. For that you would have to upload server side sourcemaps as well.

VadymBoguslavsky commented 5 years ago

Ok, sorry but it seems that i cant understand something, this is our global:

global ->>> Object [global] {
  global: [Circular],
  clearInterval: [Function: clearInterval],
  clearTimeout: [Function: clearTimeout],
  setInterval: [Function: setInterval],
  setTimeout: [Function: setTimeout] { [Symbol(util.promisify.custom)]: [Function] },
  queueMicrotask: [Function: queueMicrotask],
  clearImmediate: [Function: clearImmediate],
  setImmediate: [Function: setImmediate] {
    [Symbol(util.promisify.custom)]: [Function]
  },
  '__core-js_shared__': {
    versions: [ [Object] ],
    wks: {
      toStringTag: Symbol(Symbol.toStringTag),
      _hidden: Symbol(Symbol._hidden),
      toPrimitive: Symbol(Symbol.toPrimitive),
      hasInstance: Symbol(Symbol.hasInstance),
      isConcatSpreadable: Symbol(Symbol.isConcatSpreadable),
      iterator: Symbol(Symbol.iterator),
      match: Symbol(Symbol.match),
      replace: Symbol(Symbol.replace),
      search: Symbol(Symbol.search),
      species: Symbol(Symbol.species),
      split: Symbol(Symbol.split),
      unscopables: Symbol(Symbol.unscopables),
      asyncIterator: Symbol(Symbol.asyncIterator),
      observable: Symbol(Symbol.observable)
    },
    keys: { IE_PROTO: 'Symbol(IE_PROTO)_2.5e9ufk9ygw' },
    'symbol-registry': {},
    symbols: {},
    'op-symbols': {}
  },
  __DEBUG__: false,
  __extends: [Function: __extends],
  __assign: [Function: assign],
  __rest: [Function: __rest],
  __decorate: [Function: __decorate],
  __param: [Function: __param],
  __metadata: [Function: __metadata],
  __awaiter: [Function: __awaiter],
  __generator: [Function: __generator],
  __exportStar: [Function: __exportStar],
  __values: [Function: __values],
  __read: [Function: __read],
  __spread: [Function: __spread],
  __spreadArrays: [Function: __spreadArrays],
  __await: [Function: __await],
  __asyncGenerator: [Function: __asyncGenerator],
  __asyncDelegator: [Function: __asyncDelegator],
  __asyncValues: [Function: __asyncValues],
  __makeTemplateObject: [Function: __makeTemplateObject],
  __importStar: [Function: __importStar],
  __importDefault: [Function: __importDefault],
  fetch: [Function]
}

It seems our global has not _NEXTDATA on server, but on client it seems that we have it and when i starting it locally it buildId: "development"

azizhk commented 5 years ago

when i starting it locally it buildId: "development" Yeah when you build in production mode, it will generate and populate a buildId.

Regarding the buildId on server, you can use webpack's define plugin:

// next.config.js
module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
    config.plugins.push(
      new webpack.DefinePlugin({
        "process.env.APP_VERSION": JSON.stringify(buildId),
      })
    );
  }
}

This will give you the buildId in process.env.APP_VERSION

VadymBoguslavsky commented 5 years ago

Sorry but it seems that it`s all the same(

Screen Shot 2019-09-13 at 2 12 23 PM

Now in config:

       config.plugins.push(
          new webpack.DefinePlugin({
            "process.env.APP_VERSION": JSON.stringify(buildId),
          })
        );

      if (!dev) {
        config.plugins.push(
          new BugsnagSourceMapUploaderPlugin({
            apiKey: '**************',
            appVersion: process.env.APP_VERSION,
            publicPath: '*/',
            override: true,
            uploadSource: true
          })
        );
      } 

and in bugsnag config is

import React from 'react';
import bugsnag from '@bugsnag/js';
import bugsnagReact from '@bugsnag/plugin-react';
import config from '../config';

const bugsnagClient = bugsnag({
  apiKey: config.apiKey,
  notifyReleaseStages: ['production', 'staging'],
  appVersion: process.browser
    ? global.__NEXT_DATA__.buildId
    : process.env.APP_VERSION
});

bugsnagClient.use(bugsnagReact, React);

export default bugsnagClient;
azizhk commented 5 years ago

No need to do

  appVersion: process.browser
    ? global.__NEXT_DATA__.buildId
    : process.env.APP_VERSION

Now you can directly use process.env.APP_VERSION for both client and server.

mattdyoung commented 5 years ago

@VadymBoguslavsky I'd suggest if you're still having issues you contact support@bugsnag.com with full details of your config and a link to an example of an error in your dashboard which hasn't correctly mapped which will enable us to analyze the root cause much more quickly.

lifeiscontent commented 4 years ago

@mattdyoung seems a recent version of next.js broke sourcemaps again. Should I reach out to support@bugsnag.com?

abigailbramble commented 4 years ago

Hey @lifeiscontent if you're ever experiencing any issues, please don't hesitate to reach out to support@bugsnag.com!

zhirzh commented 1 week ago

same problem exists in nextjs 14 with server pages sourcemaps. looking inside the compilation stats object, i found that page chunk files and auxiliary files are resolved relative to outputPath which is set to .next/server/chunks:

{
  "publicPath": "/_next/",
  "outputPath": "/path/to/project/.next/server/chunks",
  "chunks": [
    {
      "names": ["pages/hello"],
      "files": ["../pages/hello.js"],
      "auxiliaryFiles": ["../pages/hello.js.map"],
      // ...
    },
    {
      "reason": "split chunk (cache group: default)",
      "names": [],
      "files": ["123.js"],
      "auxiliaryFiles": ["123.js.map"],
      // ...
    },
    // ...
  ],
  // ...
}

this causes sourcemaps to be uploaded with ".." in the url and bugsnag cannot match them to the actual pages that report issues:

<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for ".next/server/chunks/../pages/hello.js"
<i> [BugsnagSourceMapUploaderPlugin] uploading sourcemap for ".next/server/chunks/123.js"

i was able to "fix" this by deleting parent directory reference (/chunks/../ -> /). this simple change worked for my problem but i couldn't think of a more general solution.

PS: i also needed to pass publicPath to the plugin config (as @azizhk pointed out here) and use different value for server builds

new BugsnagSourceMapUploaderPlugin({
  // ...
  publicPath: isServer ? ".next/server/chunks/" : "*/_next/"
})
here is the patch for patch-package: ```diff diff --git a/node_modules/webpack-bugsnag-plugins/source-map-uploader-plugin.js b/node_modules/webpack-bugsnag-plugins/source-map-uploader-plugin.js index 8d77345..0d27417 100644 --- a/node_modules/webpack-bugsnag-plugins/source-map-uploader-plugin.js +++ b/node_modules/webpack-bugsnag-plugins/source-map-uploader-plugin.js @@ -79,14 +79,19 @@ class BugsnagSourceMapUploaderPlugin { return null } + let url = '' + + // ensure publicPath has a trailing slash + publicPath.replace(/[^/]$/, '$&/') + + // remove leading / or ./ from source + source.replace(/^\.?\//, '') + + // replace parent directory references with empty string + url = url.replace(/[^\/]+\/\.\.\//g, '') + return { source: outputChunkLocation, map: outputSourceMapLocation, - url: '' + - // ensure publicPath has a trailing slash - publicPath.replace(/[^/]$/, '$&/') + - // remove leading / or ./ from source - source.replace(/^\.?\//, '') + url } }).filter(Boolean) } ```