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

feat(utils): Modern implementation of getGlobalObject #5809

Merged
merged 3 commits into from
Sep 26, 2022

Conversation

timfish
Copy link
Collaborator

@timfish timfish commented Sep 23, 2022

This PR:

@AbhiPrasad AbhiPrasad requested review from a team, lobsterkatie and AbhiPrasad and removed request for a team September 23, 2022 15:46
@AbhiPrasad
Copy link
Member

AbhiPrasad commented Sep 23, 2022

I wonder if we can also clean up our usage of getGlobalObject around the codebase while we do this.

edit: The Node 8 test failures 😓

@timfish
Copy link
Collaborator Author

timfish commented Sep 23, 2022

The node test failures were due to me assuming I knew better than the many hours that have been put into the core-js code 🤷‍♂️

The ember test failure look unrelated?

I wonder if we can also clean up our usage of getGlobalObject around the codebase while we do this.

There might be some options there for cleanup but it will be much easier to revert this PR if it only contains this one change 😂

@AbhiPrasad
Copy link
Member

The ember test failure look unrelated?

Yeah it's probably a flake

There might be some options there for cleanup but it will be much easier to revert this PR if it only contains this one change 😂

Yeah, let's do it in another change. We can even make a new task to track that!

@AbhiPrasad AbhiPrasad changed the title feat: Modern implementation of getGlobalObject feat(utils): Modern implementation of getGlobalObject Sep 23, 2022
@lforst
Copy link
Member

lforst commented Sep 23, 2022

Screen Shot 2022-09-23 at 19 31 21

A classic 🤣

Copy link
Member

@lobsterkatie lobsterkatie left a comment

Choose a reason for hiding this comment

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

A few small suggestions for slightly easier reading, but otherwise LGTM!

(Oh, actually, one half-baked thought/question: Is there a reason we couldn't just do away with getGlobalObject() entirely and just import GLOBAL everywhere? I suppose we'd lose the typecasting we get from the generic (when we use it, which we don't always), but getGlobalObject<Widow>() vs GLOBAL as Window is kind of a wash on that score. Maybe it could be an issue with web workers?

Anyway, not saying it's necessarily better, just something to think about.)

packages/utils/src/global.ts Outdated Show resolved Hide resolved
packages/utils/src/global.ts Outdated Show resolved Hide resolved
packages/utils/src/global.ts Outdated Show resolved Hide resolved
@timfish
Copy link
Collaborator Author

timfish commented Sep 25, 2022

A few small suggestions for slightly easier reading, but otherwise LGTM!

Agree they're all much clearer. Also renamed the check function to isGlobalObj and with a more sensible param name.

Is there a reason we couldn't just do away with getGlobalObject() entirely and just import GLOBAL everywhere? I supposed we'd lose the typecasting we get from the generic (when we use it, which we don't always), but getGlobalObject() vs GLOBAL as Window is kind of a wash on that score. Maybe it could be an issue with web workers?

I would be tempted to hide the types behind different exports to reduce the use of generics everywhere and then eventually move them to the individual runtime packages:

export const GLOBAL_OBJ: SentryGlobal = /* get the global object here */;

// This would eventually end up in `@sentry/browser`
export const WINDOW = GLOBAL_OBJ as Window & SentryGlobal;

// This would eventually end up in `@sentry/node`
export const GLOBAL = GLOBAL_OBJ as NodeJs.Global & SentryGlobal;

// This would eventually end up in `@sentry/some-runtime`
export const GLOBAL_THIS = GLOBAL_OBJ as GlobalThis & SentryGlobal;

This might go against some of the reasoning here, however the current typecasting with getGlobalObject allows us to be quite sloppy about which packages we put code in. I would argue that if we want to enforce that the core packages are runtime agnostic, whatever we replace getGlobalObject<Window>() with, it should only be accessible in packages where window actually exists.

With the above code, we'd still have full runtime global object detection but the types would be be a lot more strict around different runtimes.

@lobsterkatie
Copy link
Member

Ah, right, thanks for linking to that comment of Kamil's. Yeah, that's what I meant about it possibly being an issue for web workers - exactly what he mentions about them not having window defined. If we moved to only using your WINDOW constant in @sentry/browser, would that end up being a problem?

@timfish
Copy link
Collaborator Author

timfish commented Sep 26, 2022

Yeah, that's what I meant about it possibly being an issue for web workers - exactly what he mentions about them not having window defined. If we moved to only using your WINDOW constant in @sentry/browser, would that end up being a problem?

My suggestion in that discussion was to just use window where it's available and there are issues with that.

However, WINDOW above would work with web workers as is just a typecasted reference of GLOBAL_OBJ which will end up being self in a web worker. It's functionally equivalent to getGlobalObject<Window>().

If we have a global type that we want to use in both browser and web worker contexts, we probably should create a union type to reflect what is available in both with optional properties for what is only available in one context. Using the Window type as the global in web workers has risks because that is not a true representation of the global scope there.

@AbhiPrasad
Copy link
Member

I would be tempted to hide the types behind different exports to reduce the use of generics everywhere and then eventually move them to the individual runtime packages

I'm a big fan of this idea, can we try experimenting with this as a next step?

If we have a global type that we want to use in both browser and web worker contexts

I think we should generally assume that this is the case, and that either self or window will be returned, we should adjust the type there accordingly.

I'm going to go ahead and merge this because it'll help unblock the rest of the work we have to do here.

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.

4 participants