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

Tech: improve global types #20184

Merged
merged 40 commits into from
Dec 20, 2022

Conversation

ndelangen
Copy link
Member

@ndelangen ndelangen commented Dec 9, 2022

Issue:

Closes: #19386

What I did

strong typing for globals
fix issues resulting from strong global types

I ran into this global package not having any types, and got mad at it, so I created https://github.com/ndelangen/global
Now global types are not any, and reflect the globalThis.

ndelangen and others added 6 commits December 1, 2022 18:33
The issue is vite doesn't pass certain files throw the transform plugin, this causes the globalization to not be complete, causing multiple version of the same module, which is designed to be a singleton.

me and Ian looked at it, we need to investigate further.

Co-authored-by: Ian VanSchooten <ian.vanschooten@gmail.com>
@ndelangen ndelangen self-assigned this Dec 9, 2022
@ndelangen ndelangen added the bug label Dec 9, 2022
@ndelangen ndelangen changed the title strong typing for globals, fix issues resulting from strong global types, enforce clientApi singleton via global Fix: enforce clientApi singleton via global Dec 9, 2022
@ndelangen
Copy link
Member Author

I need to verify this actually fixes the vite dev issue

@IanVS
Copy link
Member

IanVS commented Dec 12, 2022

I'd love to find some time to finish up #19386, to give proper types for globals.

@ndelangen ndelangen changed the base branch from next to norbert/sb-1063-vite-in-dev-mode-with-storystorev6-cleaned December 12, 2022 17:53
@ndelangen ndelangen changed the title Fix: enforce clientApi singleton via global Tech: improve global types Dec 13, 2022
@ndelangen
Copy link
Member Author

@IanVS I think this PR replaces that one

@ndelangen ndelangen force-pushed the norbert/sb-1063-vite-in-dev-mode-with-storystorev6-cleaned branch from 91fe4d8 to 775f3ae Compare December 13, 2022 11:19
Copy link
Member

@IanVS IanVS left a comment

Choose a reason for hiding this comment

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

It's a bummer there's so much duplicated work here between this and #19386, and it would be nice to avoid the use of a dependency at all, but I see the benefit to easier mocking this way, and we get some nice wins on the correct typing, which is the main reason I wanted to replace global in the first place.

I think we could probably be more rigorous on the typing of our own globals, but as I said elsewhere, I think that can come later.

I had a few small suggestions, but this looks like a good step to take.

@@ -1 +1,2 @@
declare module 'global';
/* eslint-disable @typescript-eslint/naming-convention */
declare var __STORYBOOK_STORY_STORE__: any;
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be something like StoryStore<Renderer>?

In my PR to remove the global dependency, I took a crack at defining the types for storybook globals here: https://github.com/storybookjs/storybook/pull/19386/files#diff-c945b52732b89295a5b35f8ed082c713dd8002a29420b607bfc382672e203fe0R28

Maybe you're planning to deal with these types in a separate PR, which would probably make sense since this is already a large PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah it should be. considering this is in an addon, I didn't want to pull in, types from 'far away' packages. The PR is complex as is, and this seemed to me like a good candidate for a follow-up

@@ -56,8 +56,8 @@ export function createCopyToClipboardFunction() {
return (text: string) => navigator.clipboard.writeText(text);
}
return async (text: string) => {
const tmp = document.createElement('TEXTAREA');
const focus = document.activeElement;
const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const tmp = document.createElement('TEXTAREA') as HTMLTextAreaElement;
const tmp = document.createElement('textarea');

Copy link
Member

Choose a reason for hiding this comment

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

Any reason to keep this capitalized like this? It's what's preventing TS from knowing how to correctly type it.

@@ -11,7 +11,7 @@ import type {
import { toRequireContext } from '@storybook/core-webpack';
import { normalizeStoriesEntry } from '@storybook/core-common';
import registerRequireContextHook from '@storybook/babel-plugin-require-context-hook/register';
import global from 'global';
import { global } from '@storybook/global';
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

good question, I don't know.. it's any:

Screenshot 2022-12-13 at 18 56 32

Screenshot 2022-12-13 at 18 56 37

code/lib/channel-postmessage/src/index.ts Outdated Show resolved Hide resolved
code/lib/client-logger/src/typings.d.ts Show resolved Hide resolved

const { LOGLEVEL, console } = global;
const { LOGLEVEL } = global;

type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent';
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent';
type LogLevel = typeof LOGLEVEL;

Copy link
Member Author

Choose a reason for hiding this comment

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

Ow I see what you're doing here.. I'm afraid this will likely break the TS bundling, because the typings.d.ts loading feature isn't automatic.

We'd have to add a tripple-lash directive to make that work. Perhaps we can do the reverse though? We should be able to import the type of LogLevel in the typings.d.ts file? That way we have a single source of truth.

@@ -106,6 +112,12 @@ function makeRequireContext(importMap: Record<Path, ModuleExports>) {
describe('start', () => {
beforeEach(() => {
global.DOCS_OPTIONS = { enabled: false };
// @ts-expect-error (setting this to undefined is indeed what we want to do)
Copy link
Member

Choose a reason for hiding this comment

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

Is this an indication that global.__STORYBOOK_CLIENT_API__ is typed incorrectly? I think nearly all globals should be allowed to be undefined, since they will be undefined until they are set somewhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

TypeScript doesn't like it:

Screenshot 2022-12-13 at 19 06 16

reason being:

var __STORYBOOK_CLIENT_API__: import('./modules/client-api/ClientApi').ClientApi<any>;
var __STORYBOOK_PREVIEW__: import('./modules/preview-web/PreviewWeb').PreviewWeb<any>;

I could set this to | undefined, sure... Do you think that's better?

Copy link
Member

Choose a reason for hiding this comment

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

I could set this to | undefined, sure... Do you think that's better?

I think so. That's what I did in my PR, to indicate that these values aren't always there, they have to be set during runtime, which means there's a period of time in which they are undefined. But maybe that's being overly pedantic.

@IanVS
Copy link
Member

IanVS commented Dec 13, 2022

Issues aren't enabled in your fork, so I'll ask this here. Why is window preferred over globalThis, when we're asserting that the type is globalThis?

https://github.com/ndelangen/global/blob/5e592be1b6feaa00eb1a2ed1cd1c464a16eec907/src/index.ts#L4-L7

@ndelangen
Copy link
Member Author

I copy-pasted that code from the original global package @IanVS
I didn't change much to it.
I can change it to prefer globalThis, I think.

Base automatically changed from norbert/sb-1063-vite-in-dev-mode-with-storystorev6-cleaned to next December 13, 2022 16:41
@ndelangen ndelangen merged commit d772d38 into next Dec 20, 2022
@ndelangen ndelangen deleted the norbert/sb-1063-vite-in-dev-mode-with-storystorev6 branch December 20, 2022 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants