Skip to content

Improve plugin static typing docs #97

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

Improve plugin static typing docs #97

wants to merge 1 commit into from

Conversation

lhorie
Copy link
Contributor

@lhorie lhorie commented Dec 14, 2018

No description provided.

@old-fusion-bot old-fusion-bot bot added the docs label Dec 14, 2018
@lhorie lhorie removed the docs label Dec 14, 2018
@old-fusion-bot old-fusion-bot bot added the docs label Dec 14, 2018
@UberOpenSourceBot
Copy link

Deploy preview ready.

Built with commit 9a533c3

https://deploy-preview-97--fusionjs.netlify.com

provides({bar}) {
return new ServerFoo();
}
}): any): FusionPlugin<ServerFooDeps, ServerFoo>);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are we ok with this as a recommendation?


It's possible for plugins to be non-trivial enough that they have similar but not identical type signatures on server and browser.

The recommended way to type those types of plugins is to create separate plugins and tokens for each environment:
Copy link
Member

Choose a reason for hiding this comment

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

For what it's worth, we don't follow this advice internally. There are a few places where we use the same types across environments when the actual types differ.

This is (1) partially due to retrofitting types after the fact, and (2) to avoid introducing new environment-specific tokens for the same plugins.

Copy link
Contributor Author

@lhorie lhorie Dec 14, 2018

Choose a reason for hiding this comment

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

Yeah, I'm aware that we basically lie for our own plugins, but I think for new development, we should discourage people from following that practice. Thoughts?

Copy link
Member

@alxmyth alxmyth Dec 14, 2018

Choose a reason for hiding this comment

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

Would this introduce a new implicit dependency between the browser and node plugins? What happens if a user registers one of these tokens but not the other? With a single environment-agnostic token, we don't run into this problem today.

I wonder if this is maybe a good case for why we might want to revisit more helper utilities for creating and exporting plugins.

I could see something like export default exportPlugin(browserPlugin, nodePlugin) or createBrowserPlugin and createNodePlugin to obfuscate any typing magic we do away from the user.

Copy link
Contributor Author

@lhorie lhorie Dec 14, 2018

Choose a reason for hiding this comment

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

I think they'd be different problems, but I'm more on board w/ the issues of having two separate tokens for server/browser registrations. In that case, at best, you get an error saying "Such and such token was not registered" and at worst, the runtime simply does nothing because you forgot to add the code to do it.

With a single token overloading both server and client type, there's no way to correctly type either server-side or browser-side usage. At best you need to add type checks everywhere to disambiguate a A | B type, and at worst you get uncaught runtime type errors because you used a part of the server type signature in the browser or vice-versa.

Copy link
Member

@alxmyth alxmyth Dec 14, 2018

Choose a reason for hiding this comment

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

Agreed that from a static typing perspective, different tokens makes our lives easier as it avoids the need for any hacks or type refinements.

I don't think we have (or feasibly can) address the issue of the client and server implementations having an implicit dependency upon each other that isn't codified anywhere. We do not have any error handling around this if done today to say "you are missing the server implementation for this plugin" for example. It would be the worst case from above - runtime does not work as expected, since only half of the plugin is working. A cursory glance may confuse a user as it looks like the code is there.

That being said, this trade-off is possibly sufficient if we are looking to avoid any compiler hacks (e.g. utility functions to hide this) and want a cleaner static typing experience. I'd be interested to see what other folks' opinions are here, and whether we should adopt this approach for our plugins as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also just a little concerned that we would give this advice if we don't follow it ourselves. If we are going to document this approach, we should probably update our existing plugins to as well. It might be worth making a list of migrations we would have to do to follow this?

Copy link
Contributor

@KevinGrandon KevinGrandon left a comment

Choose a reason for hiding this comment

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

The docs look good, but requesting changes for the time being, until we determine a strategy around the our recommendations vs reality, and how we want to communicate that strategy.

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.

4 participants