aleph.js icon indicating copy to clipboard operation
aleph.js copied to clipboard

[RFCs] Alef Component Concept

Open ije opened this issue 4 years ago • 19 comments

A new component system will ship as part of v0.4, I want to try some new ideas to write components with JSX which should be simple, fast and typed. Those ideas are inspired by React and Svelte, it's standard JSX syntax, and with high performance AOT compiler in Rust. Core features include:

  • Born in Typescript
  • With Standard JSX Syntax
  • AOT Compiler in Rust
  • No Virtual DOM
  • Reactive
  • Builtin Styling
  • SSR
import Logo from './Logo.alef'

const name: Prop<string> = 'World' // prop

let n: number = 0 // state
const double: Memo<number> = 2 * n // memo

// effect
$: () => {
  console.log('mounted')
  return () => console.log('unmounted')
}

function increase() {
  n++ // eq `setN(n => n+1)`
}

// elements
$t:
<div>
  <Logo />
  <h1>Hello {name}!</h1>
  <p onClick={increase}>double is {double}</p>
</div>

// styling
$style: `
  /* unused h1 (tree-shaking) */
  h1 {
    font-size: 200%;
  }
  p {
    color: ${Math.abs(n) >= 10 ? 'red' : 'green'}    
  }
`

Please star https://github.com/alephjs/alef-component to get project progress.

ije avatar Dec 01 '20 14:12 ije

I like how it uses more implicit sections like Marko instead of explicitly being separated into different parts. @ije Do you have an idea of what the compiler output may look like for it? With no runtime, would it just compile into some variable declarations and some document manipulations?

shadowtime2000 avatar Dec 01 '20 16:12 shadowtime2000

@ije I'd recommend you create the compiler and such in a different repo called alef or something to allow others to more easily use it without Aleph.

shadowtime2000 avatar Dec 01 '20 18:12 shadowtime2000

I like it's conciness though compare it with React

import { useState } from "react";

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment!</button>
    </>
  );
}
let count = 0;

<>
	<p>Count: {count}</p>
	<button onClick={() => count++}>Increment!</button>
</>

shadowtime2000 avatar Dec 01 '20 23:12 shadowtime2000

@shadowtime2000 yes, i will create a repo to implement this.

ije avatar Dec 02 '20 03:12 ije

@shadowtime2000 or no fragment

let count = 0;

<p>Count: {count}</p>;
<button onClick={() => count++}>Increment!</button>

ije avatar Dec 02 '20 03:12 ije

@shadowtime2000 or no fragment

let count = 0;

<p>Count: {count}</p>;
<button onClick={() => count++}>Increment!</button>

Wow, even better!

shadowtime2000 avatar Dec 02 '20 03:12 shadowtime2000

@ije I am not an expert on web performance and bundle size, but wouldn't having no runtime cause a big bundle size with stuff like reactivity, actually rendering stuff, and memoization?

shadowtime2000 avatar Dec 02 '20 03:12 shadowtime2000

huge application may have this issue, most applications should be lighter than react, we will see

ije avatar Dec 02 '20 03:12 ije

I think https://github.com/BuilderIO/jsx-lite and https://github.com/ryansolid/solid can be considered.

iFwu avatar Dec 08 '20 05:12 iFwu

@iFwu What exactly do you mean by that? The compiler I believe will already use something like what SolidJS does, except I think in some cases it won't even do that.

shadowtime2000 avatar Dec 08 '20 05:12 shadowtime2000

hey @iFwu, as @shadowtime2000 mentioned, the AOT compiler will transpile JSX to native Dom operations, no need to compile template in browser like solid do

ije avatar Dec 08 '20 06:12 ije

Thanks for replying. I got the difference now. At first look, I thought the concept is fairly alike to SolidJS. But I didn't see how the reactivity will be like in an AOT compiler. I will check Svelte for the details. If fine-grained reactivity with JSX can be implemented without templates, I'll be very excited.

iFwu avatar Dec 08 '20 06:12 iFwu

@ije After v0.3.0 will we start slowly dropping React support or something? Or will React still be supported?

shadowtime2000 avatar Dec 18 '20 17:12 shadowtime2000

@shadowtime2000 React is ever the first framework in Aleph.js, and i wish we can import react component in Alef Component in the future.

ije avatar Dec 18 '20 17:12 ije

Will we add a feature like automatic selection of components depending on usage of Alef or React? Like if we import deno.land/x/aleph/link.ts, will it automatically import a deno.land/x/aleph/link/react.ts or a deno.land/x/aleph/link/alef.alef depending on what is importing it?

shadowtime2000 avatar Jan 19 '21 02:01 shadowtime2000

I was wondering, we already have a lot of frameworks and ways to implement reactive (and non-reactive) web interfaces, do we need another one?

I think, should be better to implement other frameworks like Vue and Angular, which would fit best? Or I'm missing something?

shinspiegel avatar Jan 28 '21 14:01 shinspiegel

@shinspiegel i agree with you, the next stage(0.4) the most important idea i guess is to bring Vue to alephjs. Angular i'm not sure since i'm not the user of it.

ije avatar Jan 28 '21 14:01 ije

however, the alef component is an experience feature i want to try.

ije avatar Jan 28 '21 14:01 ije

I think Angular may not be fit for this because it has a ton of tooling that needs to be set up for it to work. Vue would be pretty nice in setting it up.

shadowtime2000 avatar Jan 28 '21 18:01 shadowtime2000