Closed ranile closed 3 years ago
I would really like to see this idea made into Yew proper.
For example, I have Angular template partials that are ~100 LOC that get really messy to deal with without proper editor/IDE support. I'd rather take an existing Angular project and just import the html files into a Yew application than copy-pasting them into the html! macro. Plus, I personally find it easier to maintain by splitting the view partial into its own file than having it live side-by-side with the component implementation.
This proposal needs some clarification. If the idea is to have a macro that behaves exactly like html!
(i.e. we pretend that the content of the HTML file is located at the call site) we end up with a few issues.
Apart from all the technical issues like macro hygiene, source span erasure, and breaking incremental compilation, I also find it very dubious to access the call site's local variables from another file.
Yew doesn't attempt to implement the HTML standard properly, it just happens to use an HTML-like syntax. The consequence of this is that tools probably won't handle the syntax properly anyway. Formatting almost certainly won't like the Rust-flavoured parts and linters will complain about various things. To give a few examples of what can go wrong: even normal text is written { "like this" }
in Yew, self-closing tags (which Yew requires for tags without a closing tag) aren't allowed for some elements as per the HTML standard, and finally, component names start with an uppercase letter but tag names are supposed to be case-insensitive (for the most part) so it might automatically lowercase it for you.
The alternative is of course to just treat the file as vanilla HTML. I don't think this is very useful because now you can't have event listeners, components, or any dynamic content really. There are a few rare cases where the content really is static (like maybe a vector graphic as seen in the inner_html example) and these are already covered by include_str!
.
Frameworks like Angular are designed with this kind of separation in mind, Yew obviously isn't. I feel like it would require entirely different html!
macro semantics in order for this to work without turning into a giant hack.
@siku2 I can't speak as to the original poster's intent, but my desire would be for some macro that does the work of reading the desired html file and running the html!
macro on those contents. Admittedly, I'm not the best with writing Rust macros, but I would envision that a macro that simply reads the file to an &str
and then calls the html macro (it should just be feeding it to the html function in the yew-macro
crate, right?) on the resultant is more than sufficient for what I would envision to be a first step. In terms of looking at it from a webpack/rollup/parcel
standpoint, Yew would just be implementing a require()
and/or import()
function.
I'm using VSCode for development and tried out the html extensions I have loaded with Yew's syntax and it behaved as expected: no difficulties with adapting to Yew-flavored HTML as if it was just handlerbars/twig/jinja2/lodash templates/every other templating language under the sun. The only pain point was the lack of Rust autocomplete, but errors in any embedded Yew-flavored HTML should be caught at compile time, no?
Finally, referring to @jstarry 's comment on the previous pull request for this feature request: does Yew really need explicit code editor experience improvements when current solutions are more than sufficient. I don't think anyone really wants to build and maintain a Yew-flavored Rust plugin for all the text editors and IDEs that are available, nor do I think that there's enough distinction in Yew-flavored HTML to warrant adding a .html.yew
file extension to the world for editors/IDEs to separate vanilla HTML from Yew-flavored HTML when the current offerings really do what's needed to make the developer experience nicer.
I think the problem here is mostly around formatting with the HTML macro (and possibly editor support, though I think that the problem there is with IntelliJ-Rust and the solution to that is to use rust-analyser which is open source, and also runs in an open source editor). I believe that it should be possible to construct a tool to format html macro invocations specifically – or perhaps look into what rustfmt does/plans to do.
Moving things into separate files works with Javascript because the Javascript ecosystem has been designed around preprocessors (e.g. module bundlers, tools to rewrite more recent syntax using older syntax, etc) and the there are therefore a number of libraries designed to work as modular parts for this sort of use case (e.g. babel which essentially offers you things like parsers, etc that you need to build these sort of systems) but I don’t think it’s a good fit for Rust.
On 7 Nov 2020, at 13:09, Joseph Quinn notifications@github.com wrote:
@siku2 https://github.com/siku2 I can't speak as to the original poster's intent, but my desire would be for some macro that does the work of reading the desired html file and running the html! macro on those contents. Admittedly, I'm not the best with writing Rust macros, but I would envision that a macro that simply reads the file to an &str and then calls the html macro (it should just be feeding it to the html function in the yew-macro crate, right?) on the resultant is more than sufficient for what I would envision to be a first step. In terms of looking at it from a webpack/rollup/parcel standpoint, Yew would just be implementing a require() and/or import() function.
I'm using VSCode for development and tried out the html extensions I have loaded with Yew's syntax and it behaved as expected: no difficulties with adapting to Yew-flavored HTML as if it was just handlerbars/twig/jinja2/lodash templates/every other templating language under the sun. The only pain point was the lack of Rust autocomplete, but errors in any embedded Yew-flavored HTML should be caught at compile time, no?
Finally, referring to @jstarry https://github.com/jstarry 's comment on the previous pull request for this feature request: does Yew really need explicit code editor experience improvements when current solutions are more than sufficient. I don't think anyone really wants to build and maintain a Yew-flavored Rust plugin for all the text editors and IDEs that are available, nor do I think that there's enough distinction in Yew-flavored HTML to warrant adding a .html.yew file extension to the world for editors/IDEs to separate vanilla HTML from Yew-flavored HTML when the current offerings really do what's needed to make the developer experience nicer.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/yewstack/yew/issues/1441#issuecomment-723444387, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKFSTPNMHCTZWJL67YRK36LSOVBJRANCNFSM4PF5KPDA.
I can't speak as to the original poster's intent, but my desire would be for some macro that does the work of reading the desired html file and running the html! macro on those contents. Admittedly, I'm not the best with writing Rust macros, but I would envision that a macro that simply reads the file to an &str and then calls the html macro (it should just be feeding it to the html function in the yew-macro crate, right?) on the resultant is more than sufficient for what I would envision to be a first step.
This was my intent when I created this issue but after using implementation from @teymour-aldridge's fork of it, I realized that Rust code in html files doesn't play nice, especially with linters. To give you an an example, IntelliJ shows me this for a simple event listener: These are the errors/warnings pointed out by the inspector:
The only pain point was the lack of Rust autocomplete, but errors in any embedded Yew-flavored HTML should be caught at compile time, no?
They can be, but spans become an issue. The reported error doesn't tell you where the error is, or at least that's what I've observed while working with the aforementioned fork. It also broke incremental compilation which was a major pain point.
If these problems can be resolved, I believe that file-based markup would be a welcome improvement. With respect to editor support, the best solution would be have the the syntax of html!
supported via a plugin but I'm not aware of any of way to add that functionality on top of intellij-rust (I've been exclusively using IntelliJ so I don't know about state of other editors)
@teymour-aldridge I disagree with your assessment of modularization of html from models/controllers/view-models. Preprocessing like you've said with javascript has become the fad of the modern web, but preprocessing has been a part of the web, with modularization, since ye old good days of Perl and the initial introduction of PHP. Rust already has other templating libraries, such as a port of handlebars and jinja2 (which I'm currently monkeying with to see if I can get to play well with Yew). I don't agree that the idea of building off template files is not a good fit for Rust. Rather, it's a matter of getting the tooling right to do so with macro expansion rather than having to load the template compilers into the wasm
bundle.
@hamza1311 I'm using the Rust team's plugins for VSCode and Neovim. I doubt we'd be able to get them to add support for the html!
macro as a part of the main Rust plugins, nor do I know of a way to get plugins for VSCode or Neovim to alter their behavior based on a single keyword.
And just to make sure I'm on the same boat, is breaking incremental compilation due to having to manually trigger recompilation when an html file is altered? Or is it all benefits of incremental compilation?
@teymour-aldridge https://github.com/teymour-aldridge I disagree with your assessment of modularization of html from models/controllers/view-models. Preprocessing like you've said with javascript has become the fad of the modern web, but preprocessing has been a part of the web, with modularization, since ye old good days of Perl and the initial introduction of PHP. Rust already has other templating libraries, such as a port of handlebars https://crates.io/crates/handlebars and jinja2 https://crates.io/crates/tera (which I'm currently monkeying with to see if I can get to play well with Yew). I don't agree that the idea of building off template files is not a good fit for Rust. Rather, it's a matter of getting the tooling right to do so with macro expansion rather than having to load the template compilers into the wasm bundle.
I feel like it’s better to minimise the use of macros and make use of the already very expressive nature Rust has – I feel like macros are an escape hatch that we don’t need to use, because the language provides all the necessary features.
On 8 Nov 2020, at 11:20, Joseph Quinn notifications@github.com wrote:
@teymour-aldridge https://github.com/teymour-aldridge I disagree with your assessment of modularization of html from models/controllers/view-models. Preprocessing like you've said with javascript has become the fad of the modern web, but preprocessing has been a part of the web, with modularization, since ye old good days of Perl and the initial introduction of PHP. Rust already has other templating libraries, such as a port of handlebars https://crates.io/crates/handlebars and jinja2 https://crates.io/crates/tera (which I'm currently monkeying with to see if I can get to play well with Yew). I don't agree that the idea of building off template files is not a good fit for Rust. Rather, it's a matter of getting the tooling right to do so with macro expansion rather than having to load the template compilers into the wasm bundle.
@hamza1311 https://github.com/hamza1311 I'm using the Rust team's plugins for VSCode and Neovim. I doubt we'd be able to get them to add support for the html! macro as a part of the main Rust plugins, nor do I know of a way to get plugins for VSCode or Neovim to alter their behavior based on a single keyword.
And just to make sure I'm on the same boat, is breaking incremental compilation due to having to manually trigger recompilation when an html file is altered? Or is it all benefits of incremental compilation?
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/yewstack/yew/issues/1441#issuecomment-723563144, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKFSTPJLL5GSJYWZSJOWPZTSOZ5GZANCNFSM4PF5KPDA.
@teymour-aldridge
I feel like it’s better to minimise the use of macros and make use of the already very expressive nature Rust has – I feel like macros are an escape hatch that we don’t need to use, because the language provides all the necessary features.
Thinking solely in the context of generating the VDom for Yew here, but the only other option for doing so would be to ship a live template rendering engine alongside the application code which would be extremely costly for performance. On top of that, you're looking at even more performance overhead with the current 'Yew way' of breaking larger partials into smaller functions. Even if a templating system for Yew was made asynchronous, it'd be slower than preprocessing the html tokens to its Rust representation during compilation, especially on limited-resource devices.
At the end of the day, everything has to end up as Rust code and I think we could provide better abstractions over that code so that you could just construct a series of function calls which would be inlined and optimised away by the compiler – there’s nothing that specifically requires the use of a macro. I haven’t investigated this very much, but it’s something that (if I every get time) I’d like to look at.
On 8 Nov 2020, at 16:04, Joseph Quinn notifications@github.com wrote:
@teymour-aldridge https://github.com/teymour-aldridge I feel like it’s better to minimise the use of macros and make use of the already very expressive nature Rust has – I feel like macros are an escape hatch that we don’t need to use, because the language provides all the necessary features.
Thinking solely in the context of generating the VDom for Yew here, but the only other option for doing so would be to ship a live template rendering engine alongside the application code which would be extremely costly for performance. On top of that, you're looking at even more performance overhead with the current 'Yew way' of breaking larger partials into smaller functions. Even if a templating system for Yew was made asynchronous, it'd be slower than preprocessing the html tokens to its Rust representation during compilation, especially on limited-resource devices.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/yewstack/yew/issues/1441#issuecomment-723604812, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKFSTPLTL2WKJ6WCKX3KB5DSO26RVANCNFSM4PF5KPDA.
At the end of the day, everything has to end up as Rust code and I think we could provide better abstractions over that code so that you could just construct a series of function calls which would be inlined and optimised away by the compiler – there’s nothing that specifically requires the use of a macro.
We're stating to get off topic, but inlining functions and macro expansion are two very different things. Inlining a function is only going to replace the function call at the site during compilation; it doesn't invoke the function call to create. As well, generally, inlining improperly will be a negative for performance, even with compiler optimizations.
As I said, using functions for generating Yew's VDom at runtime is going to be a major performance hit. Instead of doing a macro expansion at compile time such as:
You'll need to do all of that conversion from html tokens or an html string during runtime. That brings into question additions of new dependencies for handling the conversion, whether or not its safe to do the conversion of tokens in a live browser session (even sandboxed), and discussions about performance. And that list isn't even close to comprehensive.
I may not be communicating things very clearly here – I think that it should be possible to write some functions wrapping the virtual DOM which have no (or very limited) performance cost and allow one to write Rust code instead of some Rust-HTML hybrid.
Something like “hyperscript?” https://github.com/hyperhype/hyperscript
I may be wrong here :)
On 8 Nov 2020, at 17:14, Joseph Quinn notifications@github.com wrote:
At the end of the day, everything has to end up as Rust code and I think we could provide better abstractions over that code so that you could just construct a series of function calls which would be inlined and optimised away by the compiler – there’s nothing that specifically requires the use of a macro.
We're stating to get off topic, but inlining functions and macro expansion are two very different things. Inlining a function is only going to replace the function call at the site during compilation; it doesn't invoke the function call to create. As well, generally, inlining improperly will be a negative for performance, even with compiler optimizations.
As I said, using functions for generating Yew's VDom at runtime is going to be a major performance hit. Instead of doing a macro expansion at compile time such as:
https://camo.githubusercontent.com/8c3ea24b285a5d1d73ddc4e72b010c79e248b26bf11f462bf4d046f9366a8169/68747470733a2f2f692e696d6775722e636f6d2f375850675630792e706e67 You'll need to do all of that conversion from html tokens or an html string during runtime. That brings into question additions of new dependencies for handling the conversion, whether or not its safe to do the conversion of tokens in a live browser session (even sandboxed), and discussions about performance. And that list isn't even close to comprehensive.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/yewstack/yew/issues/1441#issuecomment-723638983, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKFSTPJXXWHP4EK73OGIT4TSO3GXLANCNFSM4PF5KPDA.
Something like “hyperscript?” https://github.com/hyperhype/hyperscript
Looking at hyperscript, it's essentially just a functional-looking wrapper for document.createElement
.
That's, again, a runtime hit, but on the javascript side. You're looking at something that will perform worse than static html, especially at the scale of a modern webapp.
@teymour-aldridge maybe we should split future discussion of this off into another feature request thread? We're starting to really venture off the topic of somehow implementing reading html into Yew's html!
macro now.
Agreed :)
This sort of discussion is also not ideal for a Github issue thread, but definitely worth having.
On 8 Nov 2020, at 18:36, Joseph Quinn notifications@github.com wrote:
Something like “hyperscript?” https://github.com/hyperhype/hyperscript https://github.com/hyperhype/hyperscript Looking at hyperscript, it's essentially just a functional-looking wrapper for document.createElement.
That's, again, a runtime hit, but on the javascript side. You're looking at something that will perform worse than static html, especially at the scale of a modern webapp.
@teymour-aldridge https://github.com/teymour-aldridge maybe we should split future discussion of this off into another feature request thread? We're starting to really venture off the topic of somehow implementing reading html into Yew's html! macro now.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/yewstack/yew/issues/1441#issuecomment-723648740, or unsubscribe https://github.com/notifications/unsubscribe-auth/AKFSTPITADR2JOQRI3XD6BLSO3QJLANCNFSM4PF5KPDA.
@teymour-aldridge It'd be better to open another thread so the project has a written, searchable record of what was discussed.
So I think the broad conclusion was that this is not practical to do.
@quinnjr I've written a small crate called Malvolio (https://github.com/lovelace-ed/lovelace – look in utils/malvolio
) which might give you a better idea as to what I'm thinking of.
I agree that if we were to read from a file this would need to be done with a macro for performance reasons.
I guess we can close this?
I guess we can close this?
Agreed
Describe the feature you'd like Ability to read HTML code from a file with macro like
html_from_file!
that parses from HTML (or similar) file. In case of invalid input, it fails at compile time.Is your feature request related to a problem? Please describe. The current html! really messes up IDEs. Although this can be solved with an IDE plugin which will also be needed for reading from another file but out of the box support (without plugins) would be comparatively better.
Describe alternatives you've considered Use
include!
macro to include a file but that requires that you to move thehtml!
invocation into the file which is a really messy solution.Additional context Moving HTML to another file would also allow components to have
<style>
alongside HTML which could potentially solve the component specific styles issue.Questionnaire