-
-
Notifications
You must be signed in to change notification settings - Fork 924
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
Disallow components as raw nodes #995
Comments
Thanks for this @isiahmeadows! This is effectively reverting a change introduced in 0.2.1. The changes therein are difficult to rationalise because 0.2.1 introduced way too many changes, broke a lot of stuff, and the changelog doesn't make it clear that despite the notice that 0.2.1 was nominally abandoned in favour of 0.2.2-rc1, most of 0.2.1's changelog actually made it in under the next release. I haven't gotten around to writing up my formal proposal for how to manage process and expectations for future Mithril releases — suffice to say for now that this (breaking out discrete issues into separate PRs for debate, analysis and arbitrary validation) is a huge step in the right direction :) I found out about the impact of this feature the hard way when @der-On notified me that my extension Exitable broke his application. I can testify that the implications for plugin developers is significant: The complexity of the Mithril run time is extra ambiguous since logic that would previously have executed during a top level view's execution is now deferred to a step that is difficult to pinpoint and reconcile. After thinking I had successfully patched Exitable to cater for the implications by modifying my I'm going into this level of anecdotal detail because it may prove helpful to authors of other Mithril-dependent tools trying to ensure 0.2.2 compatibility. However, I can get away with this because Exitable is a runtime executable: I suspect my fixes won't be of any use to tools like Mithril Objectify which depend upon being able to precompile virtual DOM without recourse to So AFAICT there currently remains a significant problem here for anyone who wants to be able to compile static virtual DOM trees from an Having said all this, I'm not blind to the huge convenience this brings to application authors. From an end user level, this brings componentised Mithril code into much easier reach. It's incredibly intuitive and terse to write component-invoking view code with the same grammar as JSX while retaining the full flexibility of custom component signatures etc. It would be a shame for end users to loose this feature because the current implementation is too complicated. So I'd like to ask why |
Edit: fix incorrect word. @barneycarroll Not quite what I was getting at. I'm not proposing removing // Good, still okay with this proposal
var Component = {
view: function () {
// Returns a wrapped vdom node
return m.component(SubComponent)
}
}
// What I'm proposing to make invalid
var Component = {
view: function () {
// Returns the literal component
return SubComponent
}
} In the former case, I'm also wanting to make |
My understanding of this proposal is that its goal is mainly to make life easier for mithril-objectify, and to simplify the codebase. As I mentioned in the other issue, I don't mind the breaking change. After some dogfooding, I feel I like the With that being said, I don't feel like this change would simplify the current codebase all that much, because you still need to do some type checking (currently a check for object.view, which would be replaced by a check for typeof object.tag). If I were to play devil's advocate, I could probably even argue that it's possible to add this on top of existing functionality without a breaking change. I think the biggest impact would probably be on mithril-query, if this were to land as a breaking change. Would love to hear some thoughts from @StephanHoyer on this For the rewrite, I'm about to start tackling components, and this proposal is actually one of the directions I was considering going because it happens to fit well with the code structure that I have in place. Not sure if it's helpful to describe what the new vdom structure will look like but here it is: The vdom tree is now largely inspired by cito, and there are some breaking changes at the vdom structure level (which are relevant to mithril-query cc: @StephanHoyer and mithril-objectify cc: @tivac, but shouldn't affect anyone else who's just using
As a side effect, all node types are keyable, and all node types can have lifecycle methods (currently I have oncreate, onupdate and onremove). As I mentioned, adding components w/ a structure |
I think it's not that big of a deal since I support |
As for that proposed change, I do have a few questions/remarks:
|
|
|
And the other reason I suggested this was because of memory. POJOs take up a lot less space than a dual closure with two bound functions. |
This doesn't affect any of my code in practice, so I'm easy. Removing pointless intermediary representations sounds good though. |
I didn't even realize that you could return naked components, so I don't use it and am thus fine w/ removing it. Were the docs ever updated to reference that support? I don't necessarily see how it makes life easier for @lhorie thank you SO MUCH for the details about |
@tivac You can at least do it for |
I almost have a patch ready. It hasn't had the perf tuning yet, but I'm planning on putting it up in a few, anyways, to solicit feedback. Basically, it converts nodes to use the following structure: interface VirtualNode {
tag: Component;
args: any[];
attrs: {keys: null | string | number};
} Example: assert.deepEqual(
m(Component, {key: 1}, foo, bar, baz),
{
tag: Component,
args: [{key: 1}, foo, bar, baz],
attrs: {key: 1}
}
)
assert.deepEqual(
m(Component, foo, bar, baz),
{
tag: Component,
args: [foo, bar, baz],
attrs: {key: null}
}
) |
Is this still active? Is there anyone interested in it? |
@lhorie AFAIC this is comprehensively resolved by the rewrite's virtual node API. Because this issue doesn't deal with any low level practical issues in v0.X (it's about hacking and/or high level developer concerns, not bugs), anybody with a strong stake in this should be prepared to upgrade and debate #1086. Vote to close. |
Alright, closing |
(Branched off of this comment of mine. Also, check out #994.)
TL;DR: Components should not be valid virtual nodes.
The fact components are valid nodes complicates the code base from the get go. It forces a lot of unnecessary duck typing to know if a node is a component or not. Also,
m.component()
always creates closures, which inherently decrease performance.Another thing is that it's not common in practice to use a raw component as a node, but instead just use
m(component, arg1, arg2)
. Why not only use that (or the equivalentm.component
)? It's fewer things to conceptually deal with.And for mithril-objectify users, it's not possible to convert
m(component, arg1, arg2)
into something meaningful. Disallowing raw components as valid nodes would enable something likem(component, arg1, arg2)
to be converted into something like{type: component, args: [arg1, arg2]}
This would mean making the following code invalid:
I'm curious what you all think. 😄
@barneycarroll suggested creating a new branch for developing this and #994 further and see where that takes us. Also, feel free to discuss any ideas you have about this here. 😄
/cc @lhorie @tivac @barneycarroll @pygy @ArthurClemens @StephanHoyer @mindeavor @ciscoheat
The text was updated successfully, but these errors were encountered: