-
-
Notifications
You must be signed in to change notification settings - Fork 144
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
[feature request] static HTML/CSS components #287
Comments
Yeah interesting though, I think this would require a full rewrite. Maybe one day. BTW, when you reference "components" do you mean "Web Components" https://developer.mozilla.org/en-US/docs/Web/Web_Components or just components in the general term? |
Hey sorry, just saw this. Thanks for the response. I was referring to "components" in the more general sense, as in a function that takes props and returns HTML. I can give you a more high-level explanation of what I was thinking for some more context. We've been looking for a static site generator for one of our web properties. We looked at Hugo but we weren't a huge fan of the rigidity of the templating system. I like how in modern frontend frameworks, pages can be composed of components, i.e. import Header from './Header'
import Body from './Body'
import Footer from './Footer'
const Page = () => (
<Header />
<Body />
<Footer />
) That's React-esque, but the problem we've had with React-based static site generators (e.g. Gatsby), is that React was literally created to manage "Reactive" UIs. So there's a lot of unnecessary run-time javascript for what could be mostly determined at build time. This can have a pretty major impact on performance depending on the size of your site. So there's another project I saw called https://github.com/8byt/gox (through which I found vecty). From gox's readme: "gox is an extension of Go's syntax that let's you write HTML-style tags directly in your source code." The simple example they provide is package main
import "github.com/gopherjs/vecty"
type Page struct{
vecty.Core
}
func (w *Page) Render() vecty.ComponentOrHTML {
return <body>
<div class="amazing">
<h1>gox</h1>
<span class={"you could put dynamic content here"}/>
yeah you can do bare words too
</div>
</body>
}
func main() {
vecty.RenderBody(new(Page))
} So my initial thought was this: it would be nice if there was a way for purely static components to be compiled down to static HTML at build time so that less JS can ultimately be shipped to the browser. So maybe instead of: func (w *Page) Render() vecty.ComponentOrHTML { ... } There could be another variation that just results in Static HTML. Something like: func (w *Page) Render() vecty.StaticComponentOrHTML { ... } Does that makes sense? It's just a high-level thought right now, but I think it could potentially result in more finely-tuned control over the JS that gets shipped to the browser and potentially more performant websites and apps. |
So I'm running into an issue using vecty which I have been hacking my way around: Explicitly tell vecty to skip rendering these componentsImplementing a
Issues with methodThis works in simple cases. An issue arises when creating relationships between elements where at least one implements the Since Every call of vecty.Rerender(component) is being skipped, whatever tries to call javascript code from the component which ended up not being rendered will get a undefined handler. This can be remedied by storing the first component generated as parent state as I am doing here. This ain't pretty, and I believe will get quite hairy and difficult to read when adding more. It also brings cognitive load on the user side, sadly, as I wish there was a way I as the API author or vecty could deal with it, but there seems to be none unless I can somehow dynamically seek the js object attached to a DOM node (just maybe the library has this functionality?). Solutions?Also, this got me thinking... I could just store global state since this component is likely just going to be used once. Still, this is still an issue for commodity components which need a js handler, like sliders and checkboxes. These may be present in large quantities exacerbating the problem. I'm kind of at a loss for actual sustainable solutions to this problem. |
Great solution found shortly thereafterSo global state isn't so bad on UI's, I guess? It has let me fix this issue more or less elegantly. See my recent commit on mdc. By having a The show goes on. |
@soypat I don't really understand your message above, the code is quite complex and it's not clear to me what
What are the "relationships" being talked about here?
This to me sounds like you are somehow relying on Vecty to render more elements after.. asking it not to render elements (by having a RenderSkipper implementation that always says "do not rerender")? I should make it super clear: either you or Vecty should own the element, mixing will certainly lead to bad results because Vecty has no idea about any changes you have made to the elements and expects them to be unchanged.
I don't know if it's what you want, but inside of Hope this helps |
Yeah, I was not clear at all, sorry about that.
So Ideally I should be using setUnsafeHTML to not cause problems with vecty- however, it's painful to work with strings for html rendering (I have to bring in more libraries, more cognitive load). I'd much rather write the HTML using vecty and then convert it to string somehow. This functionality would be a godsend for working with vecty's dom construction while not using it's renderer.
The problem with this approach is that since I use the RenderSkip method for all nodes with attached javascript, all user-side JS syscalls to an element which is not rerendered will fail since Mount() has not been called to set the JS handler. I was thinking this morning: Does |
There are some new static site generators out there (exhausting, I know) that support a concept of using the JSX syntax and component ideology, but they compile down to just HTML and CSS (unless you explicitly state that a component needs runtime JS). See Astro.
I could see this feature fitting nicely into this framework. I love the JSX and component-based architecture because you can keep track of your dependencies this way. HTML, scoped CSS, and JS are all in in the same file. Not to mention components literally accept dependencies.
I love go, and it seems like this library has accomplished a lot of this so far. But not everything is an SPA. Would it be possible to allow components to compile down to just HTML with no JavaScript if it wasn't required?
PS - I think it'd be advantageous to support such a feature because it'd allow consumers to ship less JS.
The text was updated successfully, but these errors were encountered: