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

Nuxt 3 compatibility #358

Closed
nandi95 opened this issue Oct 19, 2021 · 38 comments
Closed

Nuxt 3 compatibility #358

nandi95 opened this issue Oct 19, 2021 · 38 comments

Comments

@nandi95
Copy link

nandi95 commented Oct 19, 2021

With nuxt 3 out in beta, it would be nice if this module can be updated so it also supports v3.

It should be possible to support both by using @nuxt/kit.
The version 3 has said it's compatible with v2 modules but I'm seem to be experiencing issues. Is it might be because this module not using the lastest dependencies?

If this in fact meant to be working with v3, are there any way to ensure that fact with tests?

@rchl
Copy link
Member

rchl commented Oct 19, 2021

Thanks for reporting. This is discussed in https://github.com/nuxt/framework/discussions/751#discussioncomment-1468163 a bit. I would still like some answers from the team and better documentation since it's not clear how things should look going forward.

And related to that, I'm not in a rush to fix it since Nuxt 3 appears to need quite a bit of work before it stabilizes.

Open to any suggestions and help though.

@nandi95
Copy link
Author

nandi95 commented Oct 19, 2021

Missed that! Still this issue could be useful so others can find this too and for tracking support down the line.

@jontybrook
Copy link

I have written the following Nuxt 3 plugin which seems to be working fairly well for me. Note that Sentry's SDK doesn't seem to play well with the native Vue error event handler when logErrors: true is set during Sentry init; however i've added a simple console.error in the beforeSend hook so I can still see my errors in dev.

For anyone else using Nuxt 3 that this may be useful for..

  1. Add your Sentry DSN to publicRuntimeConfig.SENTRY_DSN in nuxt.config.ts, or define it manually. See other options i've sourced from runtime config below, too. Setting DSN is required; other options will fall back to defaults.
  2. Add the following in plugins/sentry.client.ts
// plugins/sentry.client.ts

import { defineNuxtPlugin, useRuntimeConfig } from '#app'
import * as Sentry from "@sentry/vue";
import { Integrations } from "@sentry/tracing";

export default defineNuxtPlugin((nuxtApp) => {
    const config = useRuntimeConfig()
    const { vueApp } = nuxtApp;
    console.log(`vueApp: `, vueApp)
    Sentry.init({
        app: [vueApp],
        dsn: config.SENTRY_DSN,
        integrations: [
            new Integrations.BrowserTracing({
                routingInstrumentation: Sentry.vueRouterInstrumentation(nuxtApp.$router),
                tracingOrigins: ["localhost", "yourdomain.com", /^\//],
            }),
        ],
        logErrors: false, // Note that this doesn't seem to work with nuxt 3
        tracesSampleRate: config.SENTRY_TRACES_SAMPLE_RATE || 1.0, // Sentry recommends adjusting this value in production
        debug: config.SENTRY_ENABLE_DEBUG || false, // Enable debug mode
        environment: config.ENVIRONMENT || 'dev', // Set environment
        // The following enables exeptions to be logged to console despite logErrors being set to false (preventing them from being passed to the default Vue err handler)
        beforeSend(event, hint) {
            // Check if it is an exception, and if so, log it.
            if (event.exception) {
                console.error(`[Exeption handled by Sentry]: (${hint.originalException})`, { event, hint })
            }
            // Continue sending to Sentry
            return event;
        },
    });

    vueApp.mixin(Sentry.createTracingMixins({ trackComponents: true, timeout: 2000, hooks: ['activate', 'mount', 'update'] }))
    Sentry.attachErrorHandler(vueApp, { logErrors: false, attachProps: true, trackComponents: true, timeout: 2000, hooks: ['activate', 'mount', 'update'] });

    return {
        provide: {
            sentrySetContext: (n, context) => Sentry.setContext(n, context),
            sentrySetUser: (user) => Sentry.setUser(user),
            sentrySetTag: (tagName, value) => Sentry.setTag(tagName, value),
            sentryAddBreadcrumb: (breadcrumb) => Sentry.addBreadcrumb(breadcrumb),
        }
    }
})
  1. Use the provided helpers in your components etc, eg:
<script setup lang="ts">
const { $sentrySetContext, $sentrySetUser } = useNuxtApp()

const throwTestError = () => {
    throw new Error('Test Error')
}

const setContext = () => {
    $sentrySetContext("character", {
        name: "Mighty Fighter",
        age: 19,
        attack_type: "melee",
    });
}

const setUser = () => {
    $sentrySetUser({ email: '[email protected]' });
}
</script>

@devlsh
Copy link

devlsh commented Apr 20, 2022

With Nuxt 3 RC1 being released in the coming days, has there been any movement on this?

@rchl
Copy link
Member

rchl commented Apr 20, 2022

Not really. If anyone knows how everything can be made to work in Nuxt 3 then feel free to contribute.

The biggest problem might be with getting it to work on the server-side (in server middleware specifically) as Nuxt 3 doesn't want modules to run at runtime and I haven't seen an equivalent to current solution for Nuxt 3.

@daniluk4000
Copy link

@rchl http://v3.nuxtjs.org/api/advanced/kit

As far as I can understand, you can call addPlugin, addServerMiddleware, and Webpack/Vite methods in module, and those settings will be applied when project start.

Is this something that will allow module to run on runtime and allow migration to Nuxt 3?

@rchl
Copy link
Member

rchl commented Apr 21, 2022

One thing that would need to be figured out is publishing of releases which relies on a webpack plugin provided by Sentry right now. It won't work with Vite.

As for using addServerMiddleware, that would have to be tested but it would be a bit awkward as we'd need to generate the file with the user options included and then add it using addServerMiddleware. Typical thing for plugins but feels a bit weird for server middleware maybe...

@daniluk4000
Copy link

daniluk4000 commented Apr 21, 2022

It won't work with Vite

Damn. That would be hard then.

@darthf1
Copy link

darthf1 commented Apr 21, 2022

I found https://github.com/ikenfin/vite-plugin-sentry, but its unofficial. I'm not using that plugin myself so I don't know if it would fit here.

@asonnleitner
Copy link

One thing that would need to be figured out is publishing of releases which relies on a webpack plugin provided by Sentry right now. It won't work with Vite.

As for using addServerMiddleware, that would have to be tested but it would be a bit awkward as we'd need to generate the file with the user options included and then add it using addServerMiddleware. Typical thing for plugins but feels a bit weird for server middleware maybe...

About that, I am looking into making a unplugin for sentry which would support, webpack, vite, rollup and esbuild. unplugin-sentry and also have made a Dev repo where I might work on the sentry module. nuxt-sentry

@rchl
Copy link
Member

rchl commented May 7, 2022

@asonnleitner appreciate the work and hope that we could use and/or merge those changes at some point.

Though it's still not fully clear to me how the situation looks like right now when it comes to module supporting both Nuxt 2 and Nuxt 3.

While @nuxt/bridge is supposedly bridging that gap and allowing for exactly that, it itself introduces breaking changes to Nuxt 2, as far as my experience goes. And since Nuxt 2 has and will have a big market share for a while longer, it would be non-ideal to either:

  • have to maintain two separate versions of the module
  • migrate to Nuxt 3 and not care about Nuxt 2 anymore

@klausXR
Copy link

klausXR commented May 20, 2022

How is this going?

Trying to migrate to nuxt-edge and this plugin doesns't seem to work. Should we ask for help or something, because I'm not sure how you can migrate any meaningful app without error reporting.

Especially at a time where you are expecting the error rate to skyrocket due to breaking changes of packages

@klausXR
Copy link

klausXR commented May 25, 2022

@danielroe can we get some insights here on the problems that are troubling the maintainers of this library?

We really need to get this module working, Sentry is the premier package for error reporting and is probably used across most of Vue/Nuxt projects.

I'm not sure any people working on production-ready apps would be willing to migrate if they don't have error reporting abilities.

@asonnleitner
Copy link

asonnleitner commented May 26, 2022

@asonnleitner appreciate the work and hope that we could use and/or merge those changes at some point.

Though it's still not fully clear to me how the situation looks like right now when it comes to module supporting both Nuxt 2 and Nuxt 3.

While @nuxt/bridge is supposedly bridging that gap and allowing for exactly that, it itself introduces breaking changes to Nuxt 2, as far as my experience goes. And since Nuxt 2 has and will have a big market share for a while longer, it would be non-ideal to either:

  • have to maintain two separate versions of the module

  • migrate to Nuxt 3 and not care about Nuxt 2 anymore

@rchl I think to make the plugin compatible with all nuxt2/bridge and 3 should not be an issue, but I am currently a bit tight with time so will take a while until I'll have a look at it in-depth.

@Harm-Nullix
Copy link

Harm-Nullix commented May 26, 2022

beforeSend

I have written the following Nuxt 3 plugin which seems to be working fairly well for me. Note that Sentry's SDK doesn't seem to play well with the native Vue error event handler when logErrors: true is set during Sentry init; however i've added a simple console.error in the beforeSend hook so I can still see my errors in dev.

For anyone else using Nuxt 3 that this may be useful for..

1. Add your Sentry DSN to `publicRuntimeConfig.SENTRY_DSN` in `nuxt.config.ts`, or define it manually. See other options i've sourced from runtime config below, too. Setting DSN is required; other options will fall back to defaults.

2. Add the following in plugins/sentry.client.ts
// plugins/sentry.client.ts

import { defineNuxtPlugin, useRuntimeConfig } from '#app'
import * as Sentry from "@sentry/vue";
import { Integrations } from "@sentry/tracing";

export default defineNuxtPlugin((nuxtApp) => {
    const config = useRuntimeConfig()
    const { vueApp } = nuxtApp;
    console.log(`vueApp: `, vueApp)
    Sentry.init({
        app: [vueApp],
        dsn: config.SENTRY_DSN,
        integrations: [
            new Integrations.BrowserTracing({
                routingInstrumentation: Sentry.vueRouterInstrumentation(nuxtApp.$router),
                tracingOrigins: ["localhost", "yourdomain.com", /^\//],
            }),
        ],
        logErrors: false, // Note that this doesn't seem to work with nuxt 3
        tracesSampleRate: config.SENTRY_TRACES_SAMPLE_RATE || 1.0, // Sentry recommends adjusting this value in production
        debug: config.SENTRY_ENABLE_DEBUG || false, // Enable debug mode
        environment: config.ENVIRONMENT || 'dev', // Set environment
        // The following enables exeptions to be logged to console despite logErrors being set to false (preventing them from being passed to the default Vue err handler)
        beforeSend(event, hint) {
            // Check if it is an exception, and if so, log it.
            if (event.exception) {
                console.error(`[Exeption handled by Sentry]: (${hint.originalException})`, { event, hint })
            }
            // Continue sending to Sentry
            return event;
        },
    });

    vueApp.mixin(Sentry.createTracingMixins({ trackComponents: true, timeout: 2000, hooks: ['activate', 'mount', 'update'] }))
    Sentry.attachErrorHandler(vueApp, { logErrors: false, attachProps: true, trackComponents: true, timeout: 2000, hooks: ['activate', 'mount', 'update'] });

    return {
        provide: {
            sentrySetContext: (n, context) => Sentry.setContext(n, context),
            sentrySetUser: (user) => Sentry.setUser(user),
            sentrySetTag: (tagName, value) => Sentry.setTag(tagName, value),
            sentryAddBreadcrumb: (breadcrumb) => Sentry.addBreadcrumb(breadcrumb),
        }
    }
})
3. Use the provided helpers in your components etc, eg:
<script setup lang="ts">
const { $sentrySetContext, $sentrySetUser } = useNuxtApp()

const throwTestError = () => {
    throw new Error('Test Error')
}

const setContext = () => {
    $sentrySetContext("character", {
        name: "Mighty Fighter",
        age: 19,
        attack_type: "melee",
    });
}

const setUser = () => {
    $sentrySetUser({ email: '[email protected]' });
}
</script>

I do not really care about the message, so it will be fine, but I am getting the following error when I use this code:
[Exeption handled by Sentry]: (TypeError: proxy set handler returned false for property '"$_sentrySpans"')

Again, it does not really make sense, but also I am not depended on it, so it will be fine for me. Just curious..
I found that it has to do with the trackComponents aprt of the tracing mixin

@rchl
Copy link
Member

rchl commented May 31, 2022

@rchl I think to make the plugin compatible with all nuxt2/bridge and 3 should not be an issue, but I am currently a bit tight with time so will take a while until I'll have a look at it in-depth.

Just installing the @nuxt/bridge creates incompatibilities as it switches to the new h3 server-side rendering engine. I guess it's probably possible to disable h3 but then it should probably not be enabled by default IMO.

@akasection
Copy link

For server side, I kinda manage to run Sentry node at bare minimum (still not working great tho, I think)

// plugins/sentry.server.ts
import * as Sentry from '@sentry/node';
import '@sentry/tracing'; // Side-effect the tracing init

export default defineNuxtPlugin(app => {
  Sentry.init({ ... });

  return {
    provide: {
      sentry: Sentry,
    }
  };
});

Combined with the sentry.client.ts above, the TS will generate the distinct type between sentry node & vue.
Though, it needs a bit hack and transpilation on nuxt config

build: {
  transpile: ['@sentry/node'],
},
alias: {
  '@sentry/utils/esm/buildPolyfills.js': '@sentry/utils/esm/buildPolyfills/index.js',
},

@ffxsam
Copy link

ffxsam commented Sep 2, 2022

@akasection Stupid question: how did you realize you had to include @sentry/node in the build.transpile option?

@akasection
Copy link

@akasection Stupid question: how did you realize you had to include @sentry/node in the build.transpile option?

When I tried import @sentry/node in sentry.server.ts and run nuxt build, I noticed the .output/server referenced the library, but somehow in the node_modules, the one that imported into server build is the CJS one, while the index file is .mjs (resulting runtime error).

It's still wasteful approach tho, because instead of importing the correct ESM one, it re-transpiles the CJS dist into ESM.

@andresespinosapc
Copy link

For me, it is working in the client but not in the server. I created a plugin in sentry.server.ts with this content:

import { defineNuxtPlugin } from '#app';
// eslint-disable-next-line no-restricted-imports
import * as Sentry from '@sentry/node';
import { NODE_ENV, SENTRY_DSN } from '@/constants';

export default defineNuxtPlugin(() => {
  Sentry.init({
    logErrors: true,
    dsn: SENTRY_DSN,
    environment: NODE_ENV,
    normalizeDepth: 5,
  });
});

Does anyone know what I'm doing wrong?

@ffxsam
Copy link

ffxsam commented Sep 26, 2022

@andresespinosapc I have to manually pull it in from useNuxtApp(), e.g.:

import * as Sentry from '@sentry/serverless';

export default defineNuxtPlugin(() => {
  return {
    provide: { sentryServer: Sentry },
  };
});

And then in the code:

const { $sentryServer } = useNuxtApp();

@akasection
Copy link

@andresespinosapc try transpile the @sentry/node under nuxt.config > build so it will transform into ESM one.

@daniluk4000
Copy link

@rchl hello there.

getsentry/sentry-webpack-plugin#375 (comment)
https://github.com/getsentry/sentry-javascript-bundler-plugins

Once this new plugin is finished, will you be able to add support for Vite in this plugin?

Also, do you have any status for your Nuxt 3 migration plans? It will be out of RC pretty soon now.

@rchl
Copy link
Member

rchl commented Oct 28, 2022

Once this new plugin is finished, will you be able to add support for Vite in this plugin?

Same answer as in #433 (comment) but I'm sure someone could contribute to this project and it wouldn't have to be me.

Also, do you have any status for your Nuxt 3 migration plans? It will be out of RC pretty soon now.

I suppose this goes hand in hand with supporting Vite.

As far as going out of RC soon, what is your source? Nuxt 3 was supposed to be released early this year or something and yet new RC versions are coming out with breaking changes and new features (quite unusual for "RC").

Also, it's still unclear whether we can make a version that will be compatible with Nuxt Bridge and Nuxt 3 at the same time or are there still blocking issues that would required two separate versions of the module.

@daniluk4000
Copy link

daniluk4000 commented Oct 28, 2022

As far as going out of RC soon, what is your source?

They said in last RC 12 that they plan to make 1-2 more RCs. That can change though, but I think this Autumn it will finally release.

breaking changes and new features

Can't argue with that.

Also, it's still unclear whether we can make a version that will be compatible with Nuxt Bridge and Nuxt 3 at the same time

Nuxt team says it is possible. Do you plan to wait until Bridge becomes stable as well and then decide?

@rchl
Copy link
Member

rchl commented Oct 28, 2022

Nuxt team says it is possible. Do you plan to wait until Bridge becomes stable as well and then decide?

Yes, I personally would wait for things to stabilise and for final Nuxt 3 to be released. I don't have time to deal with breaking changes and keep updating things for each RC. If someone else wants to deal with that then there is an option of contributing.

Also, last time I've tried to attempt the migration the functionality needed for this module didn't exist in bridge/Nuxt 3.
At least if we want to have parity with the Nuxt 2 version we need to be able to expose Sentry instance on the server-side (server middleware specificially) and this seemed impossible before or required some weird hacks. It's possible that the situation has changed now but I haven't been keeping up with all the changes.

@daniluk4000
Copy link

I don't have time to deal with breaking changes and keep updating things for each RC

Fair enough.

if we want to have parity with the Nuxt 2 version

I guess if supporting both versions will stay impossible one day Nuxt 3-only version will become a needed thing. Long after stable release for the guys to have time to update.

@unr
Copy link

unr commented Nov 9, 2022

https://twitter.com/nuxt_js/status/1590312836412379137

Nuxt has been mentioned as nearly-stable, and will be released as stable in the coming weeks.

+1 For nuxt 3 Support on Sentry

@bmulholland
Copy link
Contributor

FYI Nuxt 3 stable is out now

@daniluk4000
Copy link

https://github.com/getsentry/sentry-javascript-bundler-plugins have reached 0.1.0 version

May I suggest this solution to @rchl problem:

  • Active support Nuxt 3 with Webpack and Vite using this new plugin above (if it's usable already ofc)
  • Move Nuxt 2 branch to maintenance mode and only fix critical errors from now on and don't update to major versions of Sentry etc
  • Add Nuxt Bridge support for Nuxt 2, at least when it and 2.16 becomes stable and releases

This:

  • Will allow us to move to Nuxt 3
  • Allow you to upgrade to Nuxt 3, Sentry v7 and this new bundler plugin (w/ Vite) with any breaking changes you want
  • Will allow you to stop active support for Nuxt 2 repo but keep it working with critical-only bug fixes (which are rare I guess in current state)
  • Will allow those who stays on Nuxt 2 update to Nuxt Bridge and 2.16, as it does not supported yet

Possible version branches I see:

  • 6.0: dead branch for <= Nuxt 2.15
  • 7.0: LTS branch for Nuxt 2.16 and Bridge. IMO LTS period of 6 months will be quite enough, but you can do 12 if you can handle this
  • 8.0: major breaking changes for Nuxt 3.0, Sentry v7 and bundler plugin support with Vite/Webpack

I'm not sure if 7.0 really needed, as I can't quite understand if upgrading this module to Bridge will inproduce breaking changes. As I could see from other libs, their Bridge version could even be minor one with no breaking changes.

Possible variants I see now:

  • If Nuxt Bridge requires breaking changes, upgrade to unstable version in 7.0 and to Nuxt 3 in 8.0
  • If Nuxt Bridge does not require breaking changes, skip it for now and wait for stable version, and upgrade to Nuxt 3 in 7.0
  • If you are not sure yet about Nuxt Bridge at all, wait until it becomes full stable and then choose from those two options above. But this'll leave all Nuxt 3 users without one very cool Sentry plugin

I hope I did help in any way with most of your concerns about this lib.

@rchl
Copy link
Member

rchl commented Nov 17, 2022

There is progress being made in #456

@daniluk4000
Copy link

There is progress being made in #456

Now I feel weird about this big message lol

But that's nice to see some progress after all!

@stefan-golus
Copy link

Any updates here?

@dmaass-thing
Copy link

Hello all together 🙂
Still no news? I would like to migrate my project to nuxt 3.

@kostia7alania
Copy link

u can write u own composable ;)

@rchl
Copy link
Member

rchl commented Mar 24, 2023

I've created #530 with a bit more concrete info.

@rchl rchl closed this as completed Mar 24, 2023
@elomonaco
Copy link

u can write u own composable ;)

care to share with the class on how to do that?

@ziaadini
Copy link

ziaadini commented Jan 8, 2024

i have created a layer, and published at npm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests