Two Programs from One Template
The last lesson showed you the graph Marko builds at compile time. This one
shows you the code it writes — because your .marko file doesn’t become
one program. It becomes two, and they look nothing alike.
price-tag/index.marko is eleven lines. There’s a script in the project,
compile.mjs, that hands it to Marko’s compiler — the same compiler your
dev server is using right now — and prints the result. It takes one
argument: which platform to compile for.
- Run
node compile.mjs htmlin the terminal. That’s what the server runs. - Run
node compile.mjs dom. That’s what the browser runs.
Read the first one. It’s a function that builds a string. _html(...)
with your markup baked in, _escape(input.label) where a value goes, and
some _el_resume markers. No DOM, no elements, no reactivity — a server
rendering a page has no future to prepare for, so it doesn’t build one. It
concatenates and streams.
Now read the second. The first line is your entire button as one static string:
export const $template = "<button><!> — <!> in cart</button>";The <!> are markers — the spots that can change. The browser clones that
string once, which is about the fastest thing a browser can do. Then:
export const $walks = /* get, next(1), replace, over(2), replace, out(1) */" D%c%l";That’s directions. The compiler worked out, at build time, how to walk from the top of the button to each changing spot, and shipped the route. The compiler leaves the human-readable version in the comment beside it. At runtime nothing searches for anything, nothing diffs anything, nothing re-renders a tree — it walks to spot two and writes.
Now change the shape of it. Add a conditional inside the button:
<if=count > 2> <strong>Bulk discount!</strong></if>Run node compile.mjs dom again. $template grew a third <!>, $walks
became " D%c%c%l" — one more replace, one more over — and _if
appeared in the imports. You changed the markup; the compiler recomputed
the route.
You should have seen $walks change under your own edit. That’s the whole
trick: the framework does the searching at build time, so your users’ phones
don’t have to.
- Installing dependencies
- Starting dev server