-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
ref(tracing): Make tracing integrations tree shakeable #4204
Conversation
size-limit report
|
Given that ember tests take longer to run than most other tests (and have been known to fail for reasons having nothing to do with whatever PR we're working on), in #3571 we stopped running them locally and on PRs*, instead only running them when merging to `master` or releasing. *Provided the PR didn't touch any of the `@sentry/ember` code As a result, we didn't catch a currently-failing ember test until later than we would have liked. To prevent that from happening again, this restores the running of ember tests (both locally and on PRs), but restricts which tests run in each circumstance, in order to prevent this change from slowing down the overall repo test suite more than necessary. Specifically: - Locally, we run tests only against the current version of ember. - In the context of a PR, we run tests against the current version, the LTS version, and a version using `embroider` (which is an optional ember compiler many people use). - When merging to `master` or creating a release, for greatest safety, we test against current, LTS, embroider, beta, and "classic" (a legacy ember version). Key changes: - Up until now, the logic controlling which set of ember tests to run has been split between a script (`run_tests.js`, which differentiated local runs from CI runs), and the GHA workflow config (`build.yml`, which differentiated PRs from merges into master and creation of releases). That work is now consolidated into the ember-try config (since ember-try is the runner which needs to know which tests to run in the first place!). - As a result of the above change, the method for forcing tests for all versions of ember to run needed to be modified. That option is now handled by a new script, `run-CI-tests.js`, which simply mimics the the third situation above by setting environment variables, thereby tricking ember-try into thinking it needs to run all tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good change! All but one of my comments are just about making it clearer to the reader what's going on and why.
On that topic:
This works because we avoid the object spread in the index, we instead just take advantage of js exporting the object correctly. See an example in the rollup repl.
Two questions here:
-
I'm not clear what you mean by "avoid object spread in the index," or what it means for JS to export the object correctly.
-
(potentially solved by solving part 1 above) What is the repl illustrating, and how? Maybe have the bad way commented out so people can switch back and forth to see the effect?
it('is exported correctly', () => { | ||
Object.keys(Integrations).forEach(key => { | ||
expect(Integrations[key as keyof typeof Integrations].id).toStrictEqual(expect.any(String)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In both its old and new versions, I find this test confusing. How does the fact that every value in the Integrations
object is itself an object with a string-valued id
property prove anything about how things are getting exported? (This applies to the version in index.test.ts
also.)
(Also, what's the advantage of the refactor here?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just made it so that we don't need to use testOnlyIfNodeVersionAtLeast
anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah good question on the value of this test. I just copied the existing one from index.bundle.test.ts
into index.test.ts
, but open to alternatives.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just made it so that we don't need to use testOnlyIfNodeVersionAtLeast anymore.
I figured that might be the case. My thought about that, though, is that if you leave aside the node restriction, IMHO the old test is simpler, because you don't need the keyof typeof stuff, and since we're about to drop node 6 compatibility anyway, we could just remove the wrapper when we do and still get to have a simpler test. What do you think?
That said, yeah, first we have to figure out if we even want the test in the first place! My issue with it is less "is there value in testing the exportation?" (though I'm iffy on that) and more "okay, but how does any of this prove that it's exported correctly?". Do you understand the logic there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
whether to deal with it here or come back to it
I will come back to this and address this in another PR. You make great points that we have to figure out.
`ReportTypes` is an interally used enum, so we do not need the runtime support. The `ReportTypes` enum lives in `packages/integrations/src/reportingobserver.ts` and is used by the `ReportingObserver` integration to manage report types. According to the TS docs: https://www.typescriptlang.org/docs/handbook/enums.html > Const enums can only use constant enum expressions and unlike regular enums they are completely removed during compilation. Const enum members are inlined at use sites. This is possible since const enums cannot have computed members. This helps save on bundle size.
`States` is an interally used enum, so we do not need the runtime support. The `States` enum lives in `packages/utils/src/syncpromise.ts` and is used by `SyncPromise` to manage state internally. According to the TS docs: https://www.typescriptlang.org/docs/handbook/enums.html > Const enums can only use constant enum expressions and unlike regular enums they are completely removed during compilation. Const enum members are inlined at use sites. This is possible since const enums cannot have computed members. This helps save on bundle size.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice writeup! 💯
LGTM
(As for the test we're discussing above, I don't see how the logic holds water, but I'll leave the ball in your court to decide whether to deal with it here or come back to it. Happy to rubber duck if you want to talk through whether it does or doesn't make any sense.)
In getsentry/sentry-javascript#4204 we updated the `BrowserTracing` import in the JS SDK to be exported individually. We want users to use this individual import so that the other integrations are treeshaken. This patch updates our documentation to import `BrowserTracing` directly from `@sentry/tracing` instead of through the `Integrations` object, which hopefully should lead to a bundle size reduction for people.
In getsentry/sentry-javascript#4204 we updated the `BrowserTracing` import in the JS SDK to be exported individually. We want users to use this individual import so that the other integrations are treeshaken. This patch updates our documentation to import `BrowserTracing` directly from `@sentry/tracing` instead of through the `Integrations` object, which hopefully should lead to a bundle size reduction for people.
In #3978, code was introduced to prevent node tracing integrations (mongo, postgres, etc) from appearing in the browser bundle where they don't belong. However, as part of our larger push to make our code more treeshakable, we recently changed how we export those integrations[1], making the previous workaround unnecessary. As a bonus, this should fix a rendering issue some users were having when using the `fallback` flag. Tested locally and on vercel. Fixes #4090. [1] #4204
Cuts ~2kb for nextjs client gzip + minified bundle. Previously we expected users to import tracing integrations like ```js import { Integrations } from '@sentry/tracing'; const instance = new Integrations.BrowserTracing(); ``` This makes the integrations unable to be treeshaken though. To address this, we now have this individual export. We now expect users to consume BrowserTracing like so: ```js import { BrowserTracing } from '@sentry/tracing'; const instance = new BrowserTracing(); ``` This works because we avoid the object spread in the index, we instead just take advantage of js exporting the object correctly.
In #3978, code was introduced to prevent node tracing integrations (mongo, postgres, etc) from appearing in the browser bundle where they don't belong. However, as part of our larger push to make our code more treeshakable, we recently changed how we export those integrations[1], making the previous workaround unnecessary. As a bonus, this should fix a rendering issue some users were having when using the `fallback` flag. Tested locally and on vercel. Fixes #4090. [1] #4204
In getsentry/sentry-javascript#4204 we updated the `BrowserTracing` import in the JS SDK to be exported individually. We want users to use this individual import so that the other integrations are treeshaken. This patch updates our documentation to import `BrowserTracing` directly from `@sentry/tracing` instead of through the `Integrations` object, which hopefully should lead to a bundle size reduction for people.
In getsentry/sentry-javascript#4204 we updated the `BrowserTracing` import in the JS SDK to be exported individually. We want users to use this individual import so that the other integrations are treeshaken. This patch updates our documentation to import `BrowserTracing` directly from `@sentry/tracing` instead of through the `Integrations` object, which hopefully should lead to a bundle size reduction for people.
When we made the changes in #4204 (to export `BrowserTracing` directly rather than as part of `Sentry.Integrations`), we didn't make the change in the tracing CDN bundle. While It's true that there's no bundle size issue there (mongo and friends never were getting included in the CDN bundle, so there was nothing to fix), it did mean that when we changed the docs to match the above PR's changes, we ended up breaking CDN folks' usage of `BrowserTracing`. This fixes that by making the same change in the tracing CDN bundle as was made for the npm package. Fixes getsentry/sentry-docs#4722.
Supercedes #4199 and #4200
Fixes #3310 properly.
Cuts ~2kb for nextjs client gzip + minified bundle.
This works because we avoid the object spread in the index, we instead just take advantage of js exporting the object correctly. See an example in the rollup repl. For more info, see the details at the end of the PR description.
RIP Mongo in the browser tracing bundle!
Before
After
Details
We previously exported integrations in tracing like so:
because we created a new object and then exported it, the classes would always get included:
Webpack/Rollup will always include the
TracingIntegrations
object, so this means it would always pull in the classes.We changed this like so
This just makes each integration part of the module exports, so webpack/rollup can tree shake them out effectively. This way, a user can import
BrowserTracing
without bringing in the rest of the modules.Next Steps
Update docs after release so that users get this for free. They'll have to directly import
BrowserTracing
instead of doingIntegrations.BrowserTracing
.