-
Notifications
You must be signed in to change notification settings - Fork 78
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
Functional Widgets and Render Middleware #352
Conversation
src/widget-core/Registry.ts
Outdated
item.hasOwnProperty('__esModule') && | ||
item.hasOwnProperty('default') && | ||
isWidgetBaseConstructor(item.default) | ||
item && item.hasOwnProperty('__esModule') && item.hasOwnProperty('default') && isWidget(item.default) |
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 think for code splitting this needs to also check whether it's a widget factory.
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.
Updated
src/widget-core/middleware/core.ts
Outdated
|
||
const createFactory = create(); | ||
|
||
export const invalidator = createFactory(({ id }) => { |
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.
starting to wonder whether we should put these base ones in vdom itself? then we don't have to export the function itself?
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 think this is a good idea, will have more control in vdom itself also.
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.
Done
src/widget-core/tsx.ts
Outdated
export function create<T extends MiddlewareMap<any>, MiddlewareProps = ReturnType<T[keyof T]>['properties']>( | ||
middlewares: T = {} as T | ||
) { | ||
function properties<Props extends {}>() { |
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.
Would this read better as something similar to withProperties()
? Thinking about it from a perspective of making the create API more fluent, e.g.:
create().withProperties<{]>();
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 was trying to reduce the number of characters but went with properties
, I don't actually mind the with
prefix tho for it's fluency. @matt-gadd any thoughts?
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.
There's another subtle comprehension hiccup here - this method is describing the property interface as part of the factory creation, not widget creation nor rendering invocation.
Reading it as it currently stands, a user could potentially confuse it with passing actual property values as part of a 'create a widget' call; something that withProperties
or hasProperties
doesn't help with to resolve.
What about something like withAPI()
?
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.
My issue with that is that in the future, when typescript generics catch up we’d like to explore the possibility of using the function to define default properties which will leave the external property API with optional properties but enable referencing them from within widget knowing that although the external API is optional the internal API is not. For the moment typescript would prevent a user passing anything to the function as there are no arguments current.
Additionally the API of a widget is not just properties, it’s also children which again in the future is something that we’d consider exposing for the user to define perhaps with a further .children
API.
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.
Makes sense.
efaf021
to
b30630c
Compare
Can't comment much on the framework internals of this but the API simplification/consistency gains are great from a user's perspective. Is there any insight yet on how performance of this compares to an equivalent app structure using existing class-based widgets? Any discernible difference in execution/render timings or memory usage? (hoping this is an overall improvement as a whole - no real trade-offs users would need to consider when looking to develop apps in this new style). |
@sbinge we do have an implementation of a js-framework-benchmark that I have been upgrading and running using functional widgets. The performance is similar and the memory usage slightly less. I will do a side by side comparison of the two different implementation and post onto this issue. |
@sbinge running two implementations of the js-framework-benchmark, one with classes, one with functional widgets but otherwise identical corroborates the suspected performance characteristics. |
8877701
to
fd358b3
Compare
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.
Looks good to me 👍
Type: feature
The following has been addressed in the PR:
prettier
as per the readme code style guidelinesDescription:
The basic implementation to support functional widgets and render middleware. Includes one core middleware
invalidator
(open to renaming suggestions).Provides a single function
create
that returns a factory that can be used to create Dojo widgets and render middleware.Note: Currently
create
is in thetsx
module inwidget-core
, this is going to change as the feature is built on.Creates a simple widget with a properties interface:
Creates a render middleware with a properties interface:
Creates a widget with middleware that influences the property typings:
The change includes support for calling a widget directly, calling the widget directly has the added advantages to be able to infer complex properties such as a render property, but is also backward compatible for use with
w()
.Example Usages:
Related to #349