sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

"SentryWebpackPlugin is not a constructor" error during Next 14 build

Open weeksie opened this issue 1 year ago • 23 comments

Is there an existing issue for this?

  • [X] I have checked for existing issues https://github.com/getsentry/sentry-javascript/issues
  • [X] I have reviewed the documentation https://docs.sentry.io/
  • [X] I am using the latest SDK release https://github.com/getsentry/sentry-javascript/releases

How do you use Sentry?

Sentry Saas (sentry.io)

Which SDK are you using?

@sentry/nextjs

SDK Version

7.103.0

Framework Version

Next 14.1.0

(also using Expo 50)

Link to Sentry event

No response

SDK Setup

No response

Steps to Reproduce

next.config.js with

const withFonts = require('next-fonts');
const { withExpo } = require('@expo/next-adapter');
const { withSentryConfig } = require('@sentry/nextjs');

const nextConfig = {
    // We always want source maps for Sentry
    productionBrowserSourceMaps: true,
    sentry: {
        hideSourceMaps: true,
        widenClientFileUpload: true
    },
    reactStrictMode: false,
    swcMinify: true,
    redirects,
    env: {
        // For web, Vercel gives us the commit sha in VERCEL_GIT_COMMIT_SHA
        NEXT_PUBLIC_SENTRY_RELEASE: process.env.VERCEL_GIT_COMMIT_SHA,
    },
    transpilePackages: [
        '@react-native/assets-registry',
        'expo',
        'expo-apple-authentication',
        'expo-application',
        'expo-asset',
        'expo-constants',
        'expo-device',
        'expo-font',
        'expo-linear-gradient',
        'expo-location',
        'expo-modules-core',
        'expo-notifications',
        'react-native',
        'react-native-maps',
        'react-native-safe-area-context',
        'react-native-svg',
        'react-native-url-polyfill',
        'react-native-web',
        'sentry-expo'
    ],
    experimental: {
        forceSwcTransforms: true
    }
};

module.exports = withSentryConfig(withExpo(withFonts(nextConfig)), {});

Run

next build

Expected Result

Finish the next build

Actual Result


TypeError: SentryWebpackPlugin is not a constructor
--
09:22:48.728 | at Object.newWebpackFunction [as webpack] (/vercel/path0/node_modules/@sentry/nextjs/cjs/config/webpack.js:399:13)
09:22:48.728 | at getBaseWebpackConfig (/vercel/path0/node_modules/next/dist/build/webpack-config.js:1775:32)
09:22:48.728 | at async Promise.all (index 1)
09:22:48.728 | at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/trace/trace.js:151:20)
09:22:48.729 | at async webpackBuildImpl (/vercel/path0/node_modules/next/dist/build/webpack-build/impl.js:133:21)
09:22:48.729 | at async /vercel/path0/node_modules/next/dist/build/index.js:828:115
09:22:48.729 | at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/trace/trace.js:151:20)
09:22:48.729 | at async build (/vercel/path0/node_modules/next/dist/build/index.js:374:9)
09:22:48.729 | at async main (/vercel/path0/node_modules/next/dist/bin/next:155:5)
09:22:48.766 | Error: Command "next build" exited with 1

I was able to fix my build with the following patch:

diff --git a/node_modules/@sentry/nextjs/cjs/config/webpack.js b/node_modules/@sentry/nextjs/cjs/config/webpack.js
index 1f3c4e6..7cf0c4e 100644
--- a/node_modules/@sentry/nextjs/cjs/config/webpack.js
+++ b/node_modules/@sentry/nextjs/cjs/config/webpack.js
@@ -390,13 +390,13 @@ function constructWebpackConfigFunction(
         // without, the option to use `hidden-source-map` only applies to the client-side build.
         newConfig.devtool = userSentryOptions.hideSourceMaps && !isServer ? 'hidden-source-map' : 'source-map';
 
-        const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin');
+        const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin').default;
         if (SentryWebpackPlugin) {
           newConfig.plugins = newConfig.plugins || [];
           newConfig.plugins.push(new SentryCliDownloadPlugin());
           newConfig.plugins.push(
             // @ts-expect-error - this exists, the dynamic import just doesn't know about it
-            new SentryWebpackPlugin(
+            SentryWebpackPlugin(
               getWebpackPluginOptions(buildContext, userSentryWebpackPluginOptions, userSentryOptions),
             ),
           );
@@ -1066,7 +1066,7 @@ let downloadingCliAttempted = false;
 class SentryCliDownloadPlugin  {
    apply(compiler) {
     compiler.hooks.beforeRun.tapAsync('SentryCliDownloadPlugin', (compiler, callback) => {
-      const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin');
+      const SentryWebpackPlugin = utils.loadModule('@sentry/webpack-plugin').default;
       if (!SentryWebpackPlugin) {
         // Pretty much an invariant.
         return callback();

I assume that a better solution would include some sort of fallback or conditional check (perhaps this is caused by using swc transforms vs babel, etc. etc. etc.) but this patch works for my use case.

weeksie avatar Feb 29 '24 14:02 weeksie

I think this is due to the fact that the expo sdk brings its own version of the sentry webpack plugin. Please make sure your packages are not resolved weirdly. I don't think as of now we support the usecase nextjs + expo with our SDK. Use with caution!

lforst avatar Mar 04 '24 09:03 lforst

@lforst I wouldn't be surprised in the least, I just wanted to flag this as a thing in case someone else ran into the same thing or in the (I would assume quite unlikely) case that it wasn't expo related. Cheers!

weeksie avatar Mar 04 '24 13:03 weeksie

Thanks, appreciate it! I'll keep this issue open in case more people run into it but we'll likely not act on it any time soon.

lforst avatar Mar 04 '24 15:03 lforst

I'm getting the exact same error and trace with a next.config.js as simple as:

const { withSentryConfig } = require("@sentry/nextjs");

const nextConfig = {
  sentry: {
    hideSourceMaps: true,
  },
};

module.exports = withSentryConfig(nextConfig);
> Build error occurred
TypeError: SentryWebpackPlugin is not a constructor
    at Object.newWebpackFunction [as webpack] (/node_modules/@sentry/nextjs/cjs/config/webpack.js:399:13)
    at getBaseWebpackConfig (/node_modules/next/dist/build/webpack-config.js:1738:32)
    at async Promise.all (index 1)
    at async Span.traceAsyncFn (/node_modules/next/dist/trace/trace.js:147:20)
    at async webpackBuildImpl (/node_modules/next/dist/build/webpack-build/impl.js:132:21)
    at async webpackBuild (/node_modules/next/dist/build/webpack-build/index.js:165:16)
    at async /node_modules/next/dist/build/index.js:695:115
    at async Span.traceAsyncFn (/node_modules/next/dist/trace/trace.js:147:20)
    at async build (/node_modules/next/dist/build/index.js:187:29)
    at async main (/node_modules/next/dist/bin/next:157:5)
error Command failed with exit code 1.

alimony avatar Mar 05 '24 01:03 alimony

@alimony Is this also in an Expo app or standalone?

lforst avatar Mar 05 '24 08:03 lforst

@alimony Is this also in an Expo app or standalone?

Not an Expo app, it's a fairly simple Next.js app.

alimony avatar Mar 05 '24 09:03 alimony

@alimony Can you check for me what version of the webpack plugin is in your node modules?

lforst avatar Mar 05 '24 10:03 lforst

Oh, also, are any of you importing next.config.js inside your application somehow?

lforst avatar Mar 05 '24 10:03 lforst

@alimony Can you check for me what version of the webpack plugin is in your node modules?

2.14.2

Oh, also, are any of you importing next.config.js inside your application somehow?

No, not referenced anywhere in code except .eslintrc.

alimony avatar Mar 05 '24 10:03 alimony

2.14.2

That is the culprit. It should be something on version 1.x. Can you check your lockfile why it is on version 2?

lforst avatar Mar 05 '24 16:03 lforst

2.14.2

That is the culprit. It should be something on version 1.x. Can you check your lockfile why it is on version 2?

Because I explicitly installed it, to get support for stripping sourcemaps after upload (filesToDeleteAfterUpload) but before deploy, which seems like it isn't in the previous major version of the Webpack plugin. I guess I can't use these two things together…?

alimony avatar Mar 05 '24 16:03 alimony

I guess I can't use these two things together…?

@alimony Correct. In the next major version of the SDK we'll support the new webpack plugin and also hiding source maps from the outside.

lforst avatar Mar 05 '24 16:03 lforst

As a workaround I think you can try using

disableServerWebpackPlugin: true,
disableClientWebpackPlugin: true,

in next.config.js

lforst avatar Mar 05 '24 16:03 lforst

As a workaround I think you can try using

disableServerWebpackPlugin: true,
disableClientWebpackPlugin: true,

in next.config.js

Will that still generate sourcemaps for upload to Sentry? We did the above at some point, but conditionally, and I'm just trying to figure out how to fit these parts together to get both the obvious value of having sourcemaps in Sentry, while keeping them out of the product itself.

alimony avatar Mar 05 '24 16:03 alimony

@alimony That will disable the webpack plugin that ships internally with the Next.js SDK. Allowing you to use your own instance.

lforst avatar Mar 07 '24 08:03 lforst

Encountered the same issue!, which was resolved by upgrading the @sentry/nextjs version from 7.36.0 to 7.56.0.

vishwajeet1 avatar Mar 08 '24 07:03 vishwajeet1

got the same exact error on exact same version (SDK 7.107.0, NEXT 14.1.0), we dont use expo

fmiqbal avatar Mar 21 '24 05:03 fmiqbal

@fmiqbal Please see this thread for potential resolution steps or open a new issue with a reproduction example. Thank you!

lforst avatar Mar 21 '24 09:03 lforst

getting the exact same error in a pnpm monorepo where I have the NextJS app using @sentry/nextjs and a React app leveraging @sentry/webpack-plugin explicitly. Unsure how to solve this.

// NextJS app
"@sentry/nextjs": "^7.111.0"

// React app
"@sentry/react": "^7.110.1",
"@sentry/webpack-plugin": "^2.16.1",

a quick glance at the pnpm-lock.yaml file tells me that the webpack plugin version NextJS SDK is pointing to is a major version behind? image

yashsway avatar Apr 19 '24 15:04 yashsway

@yashsway Yep. Currently, the Next.js SDK depends on the webpack plugin v1. Please make sure that the versions don't collide. This is not something we can influence from within the SDK.

lforst avatar Apr 22 '24 09:04 lforst

@lforst of course. thanks for the confirmation!

for other folks, I've solved this in my case by adding the v1 version manually beside the NextJS app so the v2 version isn't picked up accidentally.

yashsway avatar Apr 30 '24 14:04 yashsway

@lforst当然。感谢您的确认!

对于其他人,我通过在 NextJS 应用程序旁边手动添加 v1 版本解决了这个问题,这样 v2 版本就不会被意外获取。

你好,如何手动添加v1版本

maguiqing avatar May 21 '24 09:05 maguiqing

Update: With version 8 of the SDK and onwards, it is using v2 of the Webpack plugin.

lforst avatar May 27 '24 09:05 lforst

Closing this to keep our issue stream clean. Feel free to ping us here if there are still any questions! Recommendation is to upgrade to v8 of the SDK.

lforst avatar Jun 11 '24 11:06 lforst

Hi, can you share with me the line to add to my package.json so that I have version 8 of the SDK because I didn't understand how to solve the problem.

gustavojaviercastillo avatar Aug 05 '24 19:08 gustavojaviercastillo

@gustavojaviercastillo You have a "@sentry/nextjs" field in your package json, there you can replace the 7.x.x with 8.23.0 which at the time of writing is the latest version. Don't forget to run your package manager's install command afterwards (like npm i, yarn install, or pnpm i).

lforst avatar Aug 06 '24 07:08 lforst