Stage 3 Specification
This stage includes tooling stuffs for Alef Component.
Mount
After AOT compilation, you can mount the Alef Component in browser by the mount method.
<html>
<head>
...
<head>
<body>
<main></main>
<script type="module">
import App from "./App.output.js"
(new App).mount(document.querySelector('main'))
</script>
</body>
<html>
SSR
SSR allows you to render an Alef Component to html and css strings in nodejs, Deno and broswers.
// App.alef
let name: string = 'World'
$t: <p>Hello {name}!</p>
$style: `
p {
color: green;
}
`
// renderer.ts
import { renderToString } from "https://deno.land/x/alef/ssr.ts"
import App from "./App.output.js"
const { html, css } = renderToString(App)
console.log(html, css) // output: <p class="bfl7vc">Hello World!</p> p.bfl7vc{color:green}
Hydrate in browser (thanks @shadowtime2000 suggestion):
<html>
<head>
...
<style id="alef-bfl7vc">p.bfl7vc{color:green}</style>
<head>
<body>
<main><p class="bfl7vc">Hello World!</p></main>
<script type="module">
import App from "./App.output.js"
(new App).hydrate(document.querySelector('main'))
</script>
</body>
<html>
Precompilation
Precompilation allows you to transform the source code of Alef Component before AOT compilation.
// compile.ts
import { compile, replaceStyle } from "https://deno.land/x/alef/compiler.ts"
import { compile as sass } from "https://deno.land/x/sass/mod.ts"
// Argument `source` is the raw source code without styles.
// Argument `styles` is the defined styles by `$style` label.
const sassPlugin = {
name: 'sass-loader',
precompile(source: string) => {
source = replaceStyle(source, css => {
return sass(css, {/* sass compile options */}).result
})
return source
}
}
const source = await Deno.readText("./App.alef")
const result = compile(source, {
plugins: [sassPlugin]
})
console.log(result)
Hot Refresh
Alef Component supports Hot Refresh without data losing in development, you need to config the copmiler options with hotRefresh: true.
// compile.ts
import { compile } from "https://deno.land/x/alef/compiler.ts"
const source = await Deno.readText("./App.alef")
const result = compile(source, {
hotRefresh: true
})
console.log(result)
Maybe I am reading it wrong but it seems like with SSR it only produces static strings? Is there going to be hydration and stuff?
@shadowtime2000 we can implement a hydrate method in Alef Component:
import App from "./App.output.js"
// spa
(new App).mount(document.querySelector('main'))
// ssr
(new App).hydrate(document.querySelector('main'))
@shadowtime2000 thanks, i just added your suggestion to the RFCs.
@ije Why is the mounting in stage 3? I thought that stage 3 was meant for additional stuff like SSR and hydration, shouldn't mounting be in stage 1?
@shadowtime2000 i moved it to here because i don't want to people see any html code in stage 1 - 2. And it means people should not use the mount method in stage 1 - 2 concepts.
@shadowtime2000 this week i will finish the mvp AOT compiler, but not including the css transform, i saw the project swordcss, it is cool! any idea about CSS AST parse and transform in Rust? And do you have interest in implementing it? thanks
@ije
but not including the css transform
Sorry, I am a little confused on what you mean by the CSS transform? Are you talking about minification and tree shaking? I have interest in implementing this, I know basic Rust (variables, data ownership, functions). Been meaning to expand my knowledge of it for a while...
@shadowtime2000 cool, we need to parse the css to ast, then match it with the jsx tree to implement the scope inject and tree shaking, and yes include the minification in production mode. You can check https://github.com/alephjs/alef-component/tree/main/examples/stage-2/styling to understand what it should be.
some refs:
- https://github.com/swc-project/swc/pull/950
- https://github.com/servo/rust-cssparser
- https://github.com/connorskees/grass