DEV Community

Cover image for Introducing the Marko Tags API Preview

Introducing the Marko Tags API Preview

Ryan Carniato on July 28, 2021

The Marko Tags API is a new set of Core Tags coming to Marko. They let you use state in your templates without using classes. Try this example o...
Collapse
 
dephiros profile image
An Nguyen

This is awesome! Can't wait until the optimization comes out

I have a question about cleanup of `

The tag also lets us define a cleanup method by returning a function. This method run whenever the effect is re-run, or when it is finally released

Does it mean that cleanup will be run for all dependency changes since that is when the effect is run. I only expect the effect to be run when it is released

Collapse
 
ryansolid profile image
Ryan Carniato

It does mean that. But it also makes sense. The effect makes something on each run (ie creates the side effect) and then would need to be released. It's symmetrical pair.

In order to get out of that if you create something in the effect and would want to check that it is already created on then next run you'd need to hoist that out. Hoisting that into <let> would make it stateful and cause updates itself which might not be intended.

Picture a subscription for example. You'd presumably need to know if you were already subscribed if it ever ran again. Now if the data doesn't change then you never need to re-run the effect. If it does in a way that would change what you are subscribing to, release and recreate makes sense. If it doesn't well you need to now keep track of that externally.

So if you need something that persists with a reference over multiple updates the <lifecycle> tag is exactly what you are looking for as it has a built in mechanism to preserve its references.

Collapse
 
dephiros profile image
An Nguyen

Thanks for the explanation @ryansolid !

Collapse
 
doeixd profile image
doeixd

This looks incredible, it's unlike anything else, and will take me a bit to get the hang of it. I would love to see some examples with async data. Is there something like Solid's create Resource? Thanks for the write up, Marko 6 looks to be coming along nicely

Collapse
 
ryansolid profile image
Ryan Carniato • Edited

Yeah while Marko and Solid have a shared understanding of the mechanical aspects of frameworks, including the role of reactive language and disappearing components, there are a lot differences.

In Marko, async is handled with an <await> tag that accepts a promise and displays a placeholder. It runs on the server and streams the result when it resolves into the browser.

For Marko 6 we want to do better to allow client side fetching as well. For that we intend to introduce an tag which acts as a boundary (think Suspense) and to be consistent with everything being simple values, instead of resources we will use the compiler to detect await keyword and use that to register promises inside the boundaries. In so you will be using promises directly in your code. But more often than not it will just feed into a <const> that will trigger the tag above and render the placeholder and resolve when it completes.

<attrs/{ userId }/>
<const/user = await fetchUser(userId) />
Enter fullscreen mode Exit fullscreen mode

This will be more difficult to port back into Marko 5 given the potential for wasted re-renders of the VDOM. In Marko 6's granular system (more similar to Solid) only what needs to re-reruns. We have more details to work through as async is one of the last things we are tackling but I hope that we atleast get the simple(non-concurrent) client version working during the preview time period.

Collapse
 
doeixd profile image
doeixd

Thanks. That cleared things up for me.

Collapse
 
joshuaamaju profile image
Joshua Amaju

so many questions:

  • can effects be placed in loops.
  • will the value of collapsed be reset in the example with the collapsed variable every time the loop executes.

I used to say, "it's safe using a niche framework like Marko, it's basically html with some simple extra stuff", but I guess that's no more. And finally, passing functions to components, been waiting for that.

Collapse
 
ryansolid profile image
Ryan Carniato
  1. Yes. They can be nested. You more or less can develop a child component inline with its own state. We want you to not worry as much about components but think about what makes sense for you templating out your site/application.
  2. No. I find it more helpful to think of this in the declarative model like the DOM itself rather than the imperative VDOM model. But if you think of it in terms of For loop re-running nested state does not get reset. If you think of it in the declarative sense it only runs once when each loop iteration is created and then it just keeps in sync automatically.

It is still just HTML as it ever was. Our perspective hasn't change. This article is heavy on new syntax to show it off, but in general you are writing 80% HTML, dabble in a few components, and now instead of classes you have tags. You start from the same place of just writing HTML and then adding a couple tags here and there where you need some extra behavior. We haven't taken anything away, and through co-location we hope that the change is even less jarring than before. If you have a template you wish to manage as a single piece you don't have to split it apart for performance. This should simplify things. It also reduces the need for things like component.js files etc...

Every template language adds something to make it more than just HTML. Whether you use a tag or a class, or once you had custom event handlers in any framework they have gone beyond HTML. But it's still HTML at the foundation and that is what you will be doing most of the time anyway.

Collapse
 
joshuaamaju profile image
Joshua Amaju

Thanks, this would take some time getting used to. But it solves some problems I've had with the mental model of Marko, I guess that's just a product of too much React.

Collapse
 
trusktr profile image
Joe Pea • Edited

We call this fine-grained hydration and it's made possible by the Tags API which makes it much easier to trace which values are dynamic, where they are used, and where they change. This means Marko can know exactly what code needs to run where whether on the server, in the client, or on both.

I recalled you said Marko was more for MPA's, but by the description of "fine-grained hydration" it sounds like it would work fine for SPAs too? Can someone write an SPA with Marko?

Suppose, for example, one wishes to use custom elements for 3D WebGL rendering, and thinks to use Marko for the template logic and component hierarchy of the application, while the 3D custom elements end up as the leafs in the application markup that do the actual WebGL rendering.

They intend to make a realtime RTS or FP shooter. Will this work out with Marko? How would it differ from choosing Solid.js?

Assume the user only cares about the client side experience, and whether SSR is in place or not doesn't matter much.

(I also see Marko isn't published at custom-elements-everywhere.com yet)

Collapse
 
redonkulus profile image
Seth Bertalotto

Definitely getting coldfusion vibes from many years ago. I think the tags are nice for some of the lifestyle and sideeffects issues. I'm not sure how much use they will be for server only use cases. I still like the $ {} expressiveness.

Collapse
 
ryansolid profile image
Ryan Carniato

That's the nice thing here since you just add them as needed. So if things are mostly static you are just writing normal idiomatic HTML. It almost encourages you to just add little bits here and there only as needed. But the real gains for for us is the syntax is composable unlike using a keyword and still explicit so when we get to Marko 6 this unlocks incredible things. We can basically just strip out all the static stuff in between and generate the smallest optimized bundles.

The biggest thing this does for the server case over our $ scriptlets is it forces everything to be a declaration or be denoted as a side effect. Side effects run only in the browser so it keeps things streamlined. You can always import outside JavaScript or define functions still. <const> is basically the new $ and in Marko 5 Tags preview basically compiles to it. When we reveal the new Async patterns coming I think the missing pieces will come together.