Closed 9876691 closed 1 year ago
proc_macro2
in release builds), though there is no hot reloading of components like in Dioxus.Hi! Awesome library. I don't want to create a new issue, I just want to ask. I think, this is partially related: do you plan to make the macro syntax more convenient?
For example, instead of yew-like syntax:
<h1 class="title">{ "Hello world!" }</h1>
In Dioxus you write:
h1 { class: "title", "Hello world!" }
This is a matter of taste, but it seems that such a syntax is more convenient and simpler. Personally, I don't see the point in repeating closing HTML tags. I also tried to write in Seed framework, where it looks like this:
div![
C!["title"], // shortcut for class attribute
"Hello world!",
]
There is also no need to repeat the closing tags. Although this approach has the disadvantage that you can't just copy a piece of HTML into the rust code, however, writing a view directly is much easier. It also promotes readability, unlike classic HTML.
@nanoqsh I wanted to write a short reply, and this came out, I apologize in advance as it turns out I have opinions about this :sweat_smile:.
This is obviously super subjective, but I find that style less readable, and in my experience readability always trumps writability as typing is probably the least time consuming part of me actually programming.
There is a couple factors that contribute to this:
render! {
div {
class: "col-sm-6 smallpad",
button {
class:"btn btn-primary btn-block",
r#type: "button",
id: *id,
onclick: move |_| onclick.call(()),
*name
}
}
}
Can you immediately tell whether the button
here has a body? What if it didn't need a deref, could that be a shorthand for name: name
instead?
view! {
// Keep the CSS selectors for classes, but use strings (bare identifiers for variables)
div."col-sm-6"."smallpad" {
// `id` and `onclick` are shorthands
button."btn"."btn-primary"."btn-block" [type="button", id, onclick] {
name
}
}
}
or, without CSS selector syntax:
view! {
div [class="col-sm-6 smallpad"] {
// `id` and `onclick` are shorthands
button [class="btn btn-primary btn-block", type="button", id, onclick] {
name
}
}
}
or, expanded:
view! {
div [class="col-sm-6 smallpad"] {
// `id` and `onclick` are shorthands
button [
class="btn btn-primary btn-block",
type="button",
id,
onclick,
] {
name
}
}
}
I don't hate this, but it doesn't spark joy in me either.
Simpler? Absolutely yes! It's actually harder to implement the macro the way it is since angle brackets are the only kinds of brackets that aren't treated as group delimiters in Rust token structure. Convenient? To write - sure. To read - debatable.
If your main objection is having to repeat closing tags it would be quite easy to get rid of them using </>
to infer the closing tag:
view! {
<div.col-sm-6.smallpad>
<button.btn.btn-primary.btn-block type="button" {id} {onclick}>
{name}
</>
</>
}
This way you could still put the full </div>
in if it helps readability (if opening and closing are more than half a screen apart from each other would be my heuristic), but there really isn't anything that would prevent this - there is no ambiguity about which tag name should follow </
.
Edit: To that last point I went ahead and implemented it, but I'm not sure there is really all that much value to be gained here, here is the main component of the TodoMVC example with implicit closing tags:
Some of it seems kind of worse, like the double </></>
at the end of the line for </a></p>
.
Edit 2: Just noticing this, but with CSS selectors for that h1
example, Kobold is actually the shortest already :upside_down_face::
// Yew
<h1 class="title">{ "Hello world!" }</h1>
// Dioxus
h1 { class: "title", "Hello world!" }
// Kobold
<h1.title>"Hello world!"</h1>
@maciejhirsz
Thanks for the detailed reply. I understand and fully agree that readability is more important than typing. Yes, my only complaint about HTML is the need for a meaningless tag repetition. So I find the <span>"text"</>
syntax much more satisfying.
// Yew
<h1 class="title">{ "Hello world!" }</h1>
// Dioxus
h1 { class: "title", "Hello world!" }
// Kobold
<h1.title>"Hello world!"</h1>
I can live with all of those syntaxes. And I think if you shop around other libraries have implemented them all in one form or another.
My problem is, I've had a large code base using markup.rs and the compile times seemed to get slower and slower. Things seem ok with Dioxus.
A 14 second incremental build time is awful when trying to build UI.
Just my thoughts.
My problem is, I've had a large code base using markup.rs and the compile times seemed to get slower and slower. Things seem ok with Dioxus.
Compile times in Kobold should be fine, kobold_macros
crate doesn't pull syn
or quote
(syn
is the biggest offender when it comes to compile times since it can include AST parsing for the entire Rust syntax), and only uses proc_macros2
for tests. Just looking at it markup
is using all 3, so yeah. It's not the highest priority for me, but it is always on my mind, when working on macros. I even do things like use a thread_local
ArrayString
buffer to temporarily stringify identifiers so I can inspect them without allocating strings.
My dev machine is a desktop with 5950X, so granted not your baseline laptop, but when working on TodoMVC example I get sub-1s incremental compile times.
I believe this is answered, so closing it. Feel free to reopen it if you have other questions.
@ianpurton just FYI, the PR for default parameters just landed: #67
So I've tried different HTML generators with rust, i.e. markup.rs and ructe for example.
I finally ended up using Dioxus SSR because it supports a component model.
You can see a component library I've built up here https://github.com/purton-tech/cloak/tree/main/crates/primer-rsx
The main things I need are
How does that sound?