Skip to content

ref(feedback): Create stub integrations for feedback modal & screenshot integrations #11342

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

Merged
merged 5 commits into from
Apr 9, 2024

Conversation

ryan953
Copy link
Member

@ryan953 ryan953 commented Mar 28, 2024

We're planning to split up the modal and screenshot functionality of the feedback widget into their own integrations, so they can be loaded async if folks want to do that. Loading async would have the benefit that the code is only needed when the user interacts with the feedback widget, and we're actually going to render the modal whether that be with or without the screenshot input/editor.

This PR sets up some stubs for where the code will live. There's a bunch of boilerplate for the new integrations inside packages/* and also lots of exports to setup so that the stubs are available to be imported into apps.

Currently if someone wanted to setup feedback with screenshots they would be doing:

import * as Sentry from "@sentry/browser";
import {feedbackIntegration, feedbackModalIntegration, feedbackScreenshotIntegration} from '@sentry-internal/feedback';

...
  integrations: [
    feedbackIntegration(),
    feedbackModalIntegration(),
    feedbackScreenshotIntegration(),
  ]

After this PR people will keep doing that.

In a followup PR we'll move the implementation from @sentry-internal/feedback into the new @sentry-internal/feedback-modal and @sentry-internal/feedback-screenshot, so people will be able to do this instead:

  import * as Sentry from "@sentry/browser";
- import {feedbackIntegration, feedbackModalIntegration, feedbackScreenshotIntegration} from '@sentry-internal/feedback';
+ import {feedbackIntegration} from '@sentry-internal/feedback';
+ import {feedbackModalIntegration} from '@sentry-internal/feedback-modal';
+ import {feedbackScreenshotIntegration} from '@sentry-internal/feedback-screenshot';

  ...
    integrations: [
      feedbackIntegration(),
      feedbackModalIntegration(),
      feedbackScreenshotIntegration(),
    ]

Equally valid, is people will be able to import everything from @sentry/browser too, ie import * as Sentry from "@sentry/browser"; with Sentry.feedbackScreenshotIntegration()

Related to #11435

@ryan953 ryan953 force-pushed the ryan953/feedback-integration-pkg-stubs branch from 6d8355e to 7ce768f Compare March 28, 2024 18:00
walk(filePath);
} else {
if (filePath.endsWith('.d.ts')) {
const content = fs.readFileSync(filePath, 'utf8');

Check failure

Code scanning / CodeQL

Potential file system race condition

The file may have changed since it [was checked](1).
const newContent = content.replace(preactImportRegex, '// replaced import from preact');

// and write the new content to the file
fs.writeFileSync(filePath, snippet + newContent, 'utf8');

Check failure

Code scanning / CodeQL

Potential file system race condition

The file may have changed since it [was checked](1).
walk(filePath);
} else {
if (filePath.endsWith('.d.ts')) {
const content = fs.readFileSync(filePath, 'utf8');

Check failure

Code scanning / CodeQL

Potential file system race condition

The file may have changed since it [was checked](1).
const newContent = content.replace(preactImportRegex, '// replaced import from preact');

// and write the new content to the file
fs.writeFileSync(filePath, snippet + newContent, 'utf8');

Check failure

Code scanning / CodeQL

Potential file system race condition

The file may have changed since it [was checked](1).
Copy link

codecov bot commented Mar 28, 2024

Bundle Report

Changes will decrease total bundle size by 23.53kB ⬇️

Bundle name Size Change
@sentry/types-cjs 35 bytes 0 bytes
@sentry/types-esm 35 bytes 0 bytes
@sentry/utils-cjs 174.93kB 0 bytes
@sentry/utils-esm 170.39kB 0 bytes
@sentry/core-cjs 238.78kB 0 bytes
@sentry/core-esm 235.2kB 0 bytes
@sentry-internal/feedback-screenshot-cjs 526 bytes 526 bytes ⬆️
@sentry-internal/replay-cjs 306.35kB 0 bytes
@sentry-internal/integration-shims-cjs 4.72kB 1.07kB ⬆️
@sentry-internal/feedback-modal-cjs 502 bytes 502 bytes ⬆️
@sentry/node-cjs 332.66kB 0 bytes
@sentry/vercel-edge-cjs 18.23kB 0 bytes
@sentry/node-esm 329.26kB 0 bytes
@sentry-internal/replay-esm 306.46kB 0 bytes
@sentry-internal/feedback-screenshot-esm 433 bytes 433 bytes ⬆️
@sentry-internal/replay-canvas-cjs 29.51kB 0 bytes
@sentry/aws-serverless-cjs 14.62kB 0 bytes
@sentry/browser-cjs 107.2kB 307 bytes ⬆️
@sentry-internal/node-integration-tests-cjs 1.04kB 0 bytes
@sentry/browser-esm 104.22kB 162 bytes ⬆️
@sentry/google-cloud-serverless-cjs 23.0kB 0 bytes
@sentry-internal/node-integration-tests-esm 888 bytes 0 bytes
@sentry/bun-cjs 13.5kB 0 bytes
@sentry/google-cloud-serverless-esm 19.16kB 0 bytes
@sentry/bun-esm 10.05kB 0 bytes
@sentry/react-cjs 45.04kB 0 bytes
@sentry/wasm-cjs 5.2kB 0 bytes
@sentry/react-esm 41.18kB 0 bytes
@sentry/wasm-esm 4.85kB 0 bytes
@sentry/remix-cjs 53.62kB 0 bytes
@sentry/svelte-esm 12.72kB 0 bytes
@sentry/remix-esm 48.23kB 0 bytes
@sentry/sveltekit-cjs 69.31kB 0 bytes
@sentry/astro-cjs 27.13kB 0 bytes
@sentry/sveltekit-esm 61.08kB 0 bytes
@sentry-internal/replay-canvas-esm 29.43kB 0 bytes
@sentry/astro-esm 23.39kB 0 bytes
@sentry/nextjs-cjs 20.52kB 5.02kB ⬆️
@sentry/svelte-cjs 13.84kB 0 bytes
@sentry/profiling-node-cjs 25.5kB 0 bytes
@sentry/profiling-node-esm 25.52kB 0 bytes
@sentry-internal/feedback-modal-esm 414 bytes 414 bytes ⬆️
@sentry-internal/integration-shims-esm 3.86kB 874 bytes ⬆️
@sentry-internal/feedback-cjs 65.81kB 0 bytes
@sentry-internal/tracing-cjs 65.73kB 0 bytes
@sentry/vercel-edge-esm 16.13kB 0 bytes
@sentry/opentelemetry-cjs 70.22kB 0 bytes
@sentry-internal/feedback-esm 65.5kB 0 bytes
@sentry-internal/tracing-esm 65.5kB 0 bytes
@sentry/opentelemetry-esm 69.19kB 0 bytes
@sentry/nextjs-esm 20.02kB 7.49kB ⬆️
@sentry/vue-cjs (removed) 20.19kB ⬇️
@sentry/vue-esm (removed) 18.85kB ⬇️
@sentry/gatsby-esm (removed) 385 bytes ⬇️
@sentry/gatsby-cjs (removed) 905 bytes ⬇️

Copy link
Contributor

github-actions bot commented Mar 28, 2024

size-limit report 📦

Path Size
@sentry/browser 22.07 KB (0%)
@sentry/browser (incl. Tracing) 31.69 KB (0%)
@sentry/browser (incl. Tracing, Replay) 66.89 KB (0%)
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 60.49 KB (0%)
@sentry/browser (incl. Tracing, Replay with Canvas) 70.72 KB (0%)
@sentry/browser (incl. Tracing, Replay, Feedback) 80.6 KB (0%)
@sentry/browser (incl. Feedback) 35.62 KB (0%)
@sentry/browser (incl. Feedback, Feedback Modal) 35.63 KB (-0.05% 🔽)
@sentry/browser (incl. Feedback, Feedback Modal, Feedback Screenshot) 35.64 KB (-0.03% 🔽)
@sentry/browser (incl. sendFeedback) 26.87 KB (0%)
@sentry/react 24.75 KB (0%)
@sentry/react (incl. Tracing) 34.59 KB (0%)
@sentry/vue 25.5 KB (0%)
@sentry/vue (incl. Tracing) 33.42 KB (0%)
@sentry/svelte 22.2 KB (0%)
CDN Bundle 24.12 KB (+0.17% 🔺)
CDN Bundle (incl. Tracing) 32.67 KB (+0.14% 🔺)
CDN Bundle (incl. Tracing, Replay) 66.38 KB (+0.06% 🔺)
CDN Bundle (incl. Tracing, Replay, Feedback) 80.4 KB (+0.05% 🔺)
CDN Bundle - uncompressed 71.79 KB (+0.25% 🔺)
CDN Bundle (incl. Tracing) - uncompressed 97.84 KB (+0.18% 🔺)
CDN Bundle (incl. Tracing, Replay) - uncompressed 207.23 KB (+0.09% 🔺)
@sentry/nextjs (client) 33.78 KB (0%)
@sentry/sveltekit (client) 32.21 KB (0%)
@sentry/node 120.03 KB (0%)

@ryan953 ryan953 force-pushed the ryan953/feedback-integration-pkg-stubs branch 2 times, most recently from ed3c5d5 to 47f178a Compare March 28, 2024 21:55
…ot code ot be broken out of the main integration
@mydea
Copy link
Member

mydea commented Apr 2, 2024

Just to clarify: Do we really want people to add a separate integration for the feedback modal? Should that not be the default experience?

@ryan953
Copy link
Member Author

ryan953 commented Apr 2, 2024

Just to clarify: Do we really want people to add a separate integration for the feedback modal? Should that not be the default experience?

@mydea I was thinking that aiming for the separate bundle is a good idea because it gives us options related to bundle size. Reverting the choice is super easy to do, but I haven't got the best metrics on how many bytes this 'many integration' approach will be. I'd like to compare the v8 version of @sentry-internal/feedback & @sentry-internal/feedback-modal to the v7 branch of @sentry-internal/feedback because they should have the same feature set. Differences are that the v8 code will have preact in the one bundle.

Bundle wise I think there are two groups of sentry users:

  1. The group who just wants it working, they'll copy paste the default snippet and be really happy. I don't really have a strong opinion on whether the snippet should have everything included or not. I think with the 'Create Project' flows and metrics we've seen related to replays, 1 line snippets vs 5 lines is not a problem for people.
  2. The group who cares about measuring bundle size and accounting for each byte. For these folks, I think it's important to have the lower number available, whether it's the default or not, so they can benefit from it.

I think bundle size is important with feedback in general because most people visiting a site won't click the "Give Feedback" button, so in most cases the modal will be extra bytes. Especially on mobile for example, where people might feel it more.

@billyvg
Copy link
Member

billyvg commented Apr 2, 2024

What if we had:

  • feedbackIntegration
    • includes modal in bundle
    • requires adding feedbackScreenshotIntegration
      • though we should measure how big it is, might make sense to just include this in the default bundle
  • feedbackLazyIntegration
    • will lazy load modal + screenshot via CDN (default?)
    • can accept 2 functions getModalBundle(), getScreenshotBundle which can be defined by user (i.e. getModalBundle: () => await import('@sentry/feedback-modal'))

@ryan953
Copy link
Member Author

ryan953 commented Apr 2, 2024

@billyvg I think any of these combinations are possible with the lego bits we have. Especially if we have some combinations available through the Loader, and some not.

I think the info we really need is bundle size measurements so we can better make a type-1 hard-to-undo decision related to the function signatures. The purpose after all is to lazy load some of the things, without that requirement then we wouldn't need to mess with the function signatures at all.

@Lms24
Copy link
Member

Lms24 commented Apr 3, 2024

Is there a reason to have the feedback integrations (however many we end up with) in separate packages other than being able to generate multiple bundles? This should be possible within one package by specifying multiple rollup config objects with separate entry points. I don't have a strong opinion about what is better but I'd like to avoid a situation in which we'd get circular dependencies between the feedback packages if they import from each other.
But as I said, if there's a good reason for separate packages, let's go for it - whatever you're more comfortable with.

@ryan953
Copy link
Member Author

ryan953 commented Apr 3, 2024

Is there a reason to have the feedback integrations (however many we end up with) in separate packages other than being able to generate multiple bundles? This should be possible within one package by specifying multiple rollup config objects with separate entry points. I don't have a strong opinion about what is better but I'd like to avoid a situation in which we'd get circular dependencies between the feedback packages if they import from each other.

But as I said, if there's a good reason for separate packages, let's go for it - whatever you're more comfortable with.

@Lms24 I think it'll be better to have things split up. All the code is together right now in packages/feedback but I realized that anything which the secondary packages import (npm deps or anything from core) will be duplicate bytes if @sentry/browser also makes the same import.
I think the best way to avoid import trouble is have the modal and screenshot packages import only from @sentry/types and have anything they need be passed along as function params. Separate package folders will make it clearer where the boundaries are.
I hope that makes sense

@ryan953
Copy link
Member Author

ryan953 commented Apr 4, 2024

@Lms24 @mydea @billyvg I wrote some ideas down and put them into #11435. I'm trying to sketch out the overall vision and big steps that'll get us there.

The most important next step is keeping a v8-beta release unblocked, so I'll put up the PR for that, but afterwards this PR is lays down the foundation to build on top of.

Thanks to billy also for the api help & thinking through the bundle & imports business.

ryan953 added a commit that referenced this pull request Apr 8, 2024
…the exported surface area (#11355)

You can read this commit-by-commit to watch the refactor unfold

The situation is: after
#11342 is merged, all
the code inside each of the
`packages/feedback/src/[core|modal|screenshot]` will be split up into
separate integrations. These integrations can't share the same
`src/types/*.ts` definitions anymore. Therefore type definitions will
need to live in @sentry/types instead.

This PR moves all the types, and since they'll be public now in that
package, i refactored things to reduce the public surface area and
improve names where possible.
The only non-type changes in here are where we move `createDialog.ts`
and `createInput.ts` into their respective `integration.ts` files, no
code changes at all.

Related to #11435
@ryan953 ryan953 force-pushed the ryan953/feedback-integration-pkg-stubs branch from f1f5f17 to d5e82e5 Compare April 8, 2024 21:49
@ryan953 ryan953 force-pushed the ryan953/feedback-integration-pkg-stubs branch from d5e82e5 to 0a98f8f Compare April 8, 2024 21:49
Copy link
Member

@billyvg billyvg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer waiting until the follow-up PRs are ready to merge all at once, but if branch maintenance is going to be a nightmare, it's probably fine to merge now since they don't add much to bundles.

@ryan953 ryan953 merged commit 5542127 into develop Apr 9, 2024
@ryan953 ryan953 deleted the ryan953/feedback-integration-pkg-stubs branch April 9, 2024 18:35
mydea added a commit that referenced this pull request Apr 11, 2024
mydea added a commit that referenced this pull request Apr 11, 2024
mydea added a commit that referenced this pull request Apr 11, 2024
mydea added a commit that referenced this pull request Apr 11, 2024
mydea added a commit that referenced this pull request Apr 11, 2024
)

This reverts #11342
and instead generates multiple bundles etc. from the one
`@sentry-internal/feedback` package.

* The `feedback` CDN bundle integration includes the modal integration
for now.
* There is also a dedicated modal & screenshot integration on the CDN
* Also kept the shims etc. that Ryan added in the now-reverted PR
* Size limits now seem correct to me! I bumped them (as they now
correctly include the feedback modal etc), but you can see the diff to
the screenshots being included (it's not too high, really).
cadesalaberry pushed a commit to cadesalaberry/sentry-javascript that referenced this pull request Apr 19, 2024
…the exported surface area (getsentry#11355)

You can read this commit-by-commit to watch the refactor unfold

The situation is: after
getsentry#11342 is merged, all
the code inside each of the
`packages/feedback/src/[core|modal|screenshot]` will be split up into
separate integrations. These integrations can't share the same
`src/types/*.ts` definitions anymore. Therefore type definitions will
need to live in @sentry/types instead.

This PR moves all the types, and since they'll be public now in that
package, i refactored things to reduce the public surface area and
improve names where possible.
The only non-type changes in here are where we move `createDialog.ts`
and `createInput.ts` into their respective `integration.ts` files, no
code changes at all.

Related to getsentry#11435
cadesalaberry pushed a commit to cadesalaberry/sentry-javascript that referenced this pull request Apr 19, 2024
…ot integrations (getsentry#11342)

We're planning to split up the modal and screenshot functionality of the
feedback widget into their own integrations, so they can be loaded async
if folks want to do that. Loading async would have the benefit that the
code is only needed when the user interacts with the feedback widget,
and we're actually going to render the modal whether that be with or
without the screenshot input/editor.

This PR sets up some stubs for where the code will live. There's a bunch
of boilerplate for the new integrations inside packages/* and also lots
of exports to setup so that the stubs are available to be imported into
apps.

Currently if someone wanted to setup feedback with screenshots they
would be doing:
```javascript
import * as Sentry from "@sentry/browser";
import {feedbackIntegration, feedbackModalIntegration, feedbackScreenshotIntegration} from '@sentry-internal/feedback';

...
  integrations: [
    feedbackIntegration(),
    feedbackModalIntegration(),
    feedbackScreenshotIntegration(),
  ]
```

**After this PR people will keep doing that.**

In a followup PR we'll move the implementation from
`@sentry-internal/feedback` into the new
`@sentry-internal/feedback-modal` and
`@sentry-internal/feedback-screenshot`, so people will be able to do
this instead:
```diff
  import * as Sentry from "@sentry/browser";
- import {feedbackIntegration, feedbackModalIntegration, feedbackScreenshotIntegration} from '@sentry-internal/feedback';
+ import {feedbackIntegration} from '@sentry-internal/feedback';
+ import {feedbackModalIntegration} from '@sentry-internal/feedback-modal';
+ import {feedbackScreenshotIntegration} from '@sentry-internal/feedback-screenshot';

  ...
    integrations: [
      feedbackIntegration(),
      feedbackModalIntegration(),
      feedbackScreenshotIntegration(),
    ]
```
Equally valid, is people will be able to import everything from
`@sentry/browser` too, ie `import * as Sentry from "@sentry/browser";`
with `Sentry.feedbackScreenshotIntegration()`

Related to getsentry#11435
cadesalaberry pushed a commit to cadesalaberry/sentry-javascript that referenced this pull request Apr 19, 2024
…sentry#11552)

This reverts getsentry#11342
and instead generates multiple bundles etc. from the one
`@sentry-internal/feedback` package.

* The `feedback` CDN bundle integration includes the modal integration
for now.
* There is also a dedicated modal & screenshot integration on the CDN
* Also kept the shims etc. that Ryan added in the now-reverted PR
* Size limits now seem correct to me! I bumped them (as they now
correctly include the feedback modal etc), but you can see the diff to
the screenshots being included (it's not too high, really).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants