alef-component icon indicating copy to clipboard operation
alef-component copied to clipboard

Stage 3 Specification

Open ije opened this issue 5 years ago • 9 comments

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)

ije avatar Dec 08 '20 08:12 ije

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 avatar Dec 08 '20 19:12 shadowtime2000

@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'))

ije avatar Dec 08 '20 20:12 ije

@shadowtime2000 thanks, i just added your suggestion to the RFCs.

ije avatar Dec 08 '20 20:12 ije

@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 avatar Dec 17 '20 22:12 shadowtime2000

@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.

ije avatar Dec 17 '20 22:12 ije

@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 avatar Dec 17 '20 23:12 ije

@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 avatar Dec 17 '20 23:12 shadowtime2000

@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.

ije avatar Dec 17 '20 23:12 ije

some refs:

  • https://github.com/swc-project/swc/pull/950
  • https://github.com/servo/rust-cssparser
  • https://github.com/connorskees/grass

ije avatar Dec 17 '20 23:12 ije