deno-front-end / eon

8 stars 0 forks source link

[Suggestion] ESModule Oriented Components #1

Closed SRNV closed 3 years ago

SRNV commented 3 years ago

ESModule Oriented Components (ESMOC)

the idea is to use modules for pattern of the components. all modules have only one export default, in this suggestion the default export is related to the template of the component

export default () => (<template>
  <div></div>
</template>
);

export class Model {}

getting the module all the export named are reachable with their name module.Model getting the default export of the module is reachable: module.default

SPA / SSR

changing the way we use the components and change the application's type with the cli deno-first-framework --compile-type <type>

Required

Rendering a List

2 solutions right now:

  1. using JSX common way array.map(number => <div>{ number }</div>);
  2. using UL and OL as list renderer:
    export default <ul
    for={(number) => <OtherComponent number={number}/>}
    of={state.array} />

    Strengths

    • Typescript support
    • es modules are used in both server and browser side

Constraint

SRNV commented 3 years ago

sketches

with a function as default, (should bind it to an instance of Model if defined) Screenshot from 2020-10-28 10-39-47

with an arrow function as default (can't bind it to an instance, so pass the instance of Model in argument) Screenshot from 2020-10-28 10-39-55

SRNV commented 3 years ago

update to ViewModel Screenshot from 2020-10-28 12-23-40 Screenshot from 2020-10-28 12-23-46

ebebbington commented 3 years ago

Note this is my personal opinion 👍

I think it's best to stay away from default exports, the majority of the JS community dislike them and advise against them, because it can be easier to maintain, i guess in the sense of readability. So from this, i think the effect is some people might already start with slightly negative opinions about the framework. Due to type checking, it will help refactoring when using named exports, whereas it's harder to catch when using default exports.

This also opens up the possibility of allow more exports from the module - i know it's probably not on the horizon, but what if?

ebebbington commented 3 years ago

I'd also find it more readable when using export <name> = () => {} as opposed to export () => { }

SRNV commented 3 years ago

I think we can keep export default and set also an export const template = (vm: ViewModel) => () or export function template(this: ViewModel){} for security

ebebbington commented 3 years ago

Are hooks on the horizon? or would a component be defined like:

const onNameClick = (event) => {
  ... do stuff
}
const pokemonCard = (name) => {
  return (
    <>
      <p onclick={onNameClick}>{ name }</p>
    </>
  )
}
SRNV commented 3 years ago

I don't think about hooks because this part isn't reused

export default function(this: ViewModel) {
  // nothing here
  return (<template> { this.message } </template>);
}

the function will be bound to a proxy of ViewModel and the proxy will return specific instances once I get these instances I will use a sort of template.innerHTML but all of this is made in the compiler time

SRNV commented 3 years ago

Screenshot from 2020-10-28 18-01-52

SRNV commented 3 years ago

keeping in mind that the default function is used only to get the dom tree, this create some constraints. specifically to bind the data what i propose is to use an arrow function. this will allow the deno-first-framework graph analyzer to add a textnode, replacing the function

Screenshot from 2020-10-29 11-10-21

the jsx syntax is preserved from template engine like {{ message }}.