Open TheLarkInn opened 6 years ago
Another question is what value is this providing by building into the platform? E.g. what is it providing that can't be provided by tools like webpack today. For me there is more value in standardizing on a file format for Single-File Component for ecosystem reasons.
Okay so the motivation behind this idea started when @developit told me that he was going to write a loader that would allow, preact and vue single-component files to interop seamlessly between their respective libraries/frameworks.
This is something that everyone imagined could be possible with Web Components and custom elements however as we know may still be a long ways out for implementation.
rosetta stone-like capabilities component interop between frameworks.
allow users to ship way less JavaScript and CSS to the browser
60fps scroll lists, fast dom changes, fast paints. "Does it beat the Ken Wheeler Test" (long term platform goal)
Giant company (A) is silo'd and has a variety of different frameworks that they use in house, and they all love the workflows that they have, however there is massive amounts of overlap because they cannot write components that both teams can use.
With "unity components" (Single File Components) this could be possible: Team A using Preact
(Figure 1), could use this component in the same way that Team B using 'Vue' (Figure 2) does.
Figure 1: Using Button.sfc
in .js
file and consumed with preact render()
fn
import {Button} from "material-unity" // returns a SFC "module" .sfc or .vue, etc whatever
render(
<Button someProp="whatever" />,
document.body
);
Figure 2: Using same Button.sfc
inside of a Vue single file component
<template>
<div>
<button some-prop="whatever"></button>
</div>
</template>
<script>
import {Button} from "material-unity" // returns a SFC "module" .sfc or .vue, etc whatever
export default {
components: {
Button
}
}
</script>
<style>
/* ... */
</style>
The point is that the framework-specific implementation details of how this "meta information" represented in the Single File Component are hidden through the compiler toolchains.
So although you might see data(){}
function that returns state for the component, it may instead compile to state
in react/preact, or @tracked
in GlimmerJS.
Although this statement may be opinionated, it is observed that the number one problem with web components currently is that it is a write only target, not something a framework could consume and then use (like their own systems components) without potentially substantial changes to their respective api's, renders, etc. This poses a huge challenge for adoption.
In addition, until there is cross-platform adoption for Web Components completely, there is really no interest for a majority of users or framework teams to start integrating with this system.
The magic behind what makes Vue's single file component structure so flexible and powerful, is that everything inside of their respective tags, is only a "likeness" to some extent.
For example:
<template>
<div>I look and smell like HTML, but I'm not HTML. I'm HTML-like</div>
</template>
<style>
.div {
likeness: to-css;
}
</style>
<script>
export default {
data() {
maybe: "Interpreted through the context of the component, but technically this could _not_ really be JavaScript, just a state machine's instructions"
}
}
</script>
In the same way that:
render(
<JSX>I look and smell like HTML, but I'm not html, I'm JSX, I'm html-like</JSX>,
document.body
)
So in the same way that a loader, compiler, etc. statically analyzes a .vue
file to create a JavaScript implementation of that components Dom API functionality (via VDOM), we can apply the same principle for the platform to accomplish the same thing.
In a real index.html file
<head>
<module type="unity" name="unity-button" src="./unity-components/button.sfc" />
<head>
<body>
<unity-button some-prop="whatever">Click Me</unity-button>
</body>
We have fed a single component to the browser, which consumes the SFC module, and instead of creating render functions, vdom, JSX, javascript, or anything else, it is interpreted and compiled to native instructions for the lifecycle, state, and the visual representation and behavior for that element on the DOM.
Here's some things I want to clarify before they get mentioned
A huge motivation for the use of these universal directives, is the same reason why they are great in VueJs. Although at any time, in a single-file .vue
component, a user can drop <template></template>
and instead opt-in to using render(<JSX/>, document.body)
instead.
But in the end (for vue):
<template>
<div v-for="item of 1000000items">{{item}}</div>
</template>
is just an abstraction that compiles to VDOM/Render functions to perform that ginormous scrolling list. The benefit of the platform consuming this, is that it can read that directive as an instruction to perform the same results, but in a far more, Ken Wheeler-defying-90fps-fashion (because its not DOM, or JS, its native instructions interpreted from the file).
<script>
In the same way that <template></template>
can be statically analyzed and compiled, you can take this a step further and say the use of JSX inside of <script></script>
could have a similar outcome.
<style scoped>
provides a css-like scoping solution that doesn't have to rely on shadow dom, etc.<tag>
and using. And this could potentially create a Rosetta Stone-like api for interop between a variety of frameworks (if not all). .sfc
. That way loaders can still be used to allow one to customize, extend etc while still compiling to .sfc
in browserland.Silver bullet syndrome: things that become abstracted, can lose flexibility, or have features removed to create interop. This should be carefully balanced and thought out.
Not all frameworks can statically compile these formats? (If not what is the MVP amount of changes that we could make to ensure that not only VDOM-frameworks, but also observer, watcher, and bind based libraries can leverage as well.
Can dilute the framework capabilities of a specific component type? What may work with a full rich featureset in .vue
, may need to have limited capabilities in GlimmerJS, or Polymer. (Or am I wrong. I don't know enough about them to make this assumption, but would like feedback on this.)
Pushback in browserland vs WC v2.: Although this could arise, I'm hopeful that because the .sfc
format doesn't mandate creation of API's that affect DOM (besides a new module/script type), that this could be easily worked around, and potentially alongside WC v2.
You provide this now. :joy:
There is no need to Custom Elements, it is native instructions, there needs to be no extension of existing elements or behaviors.
The non-controversial parts of Custom Elements V1 only extends HTMLElement - not arbitrary native elements. With that restriction, 62% of browsers can use them already: http://caniuse.com/#feat=custom-elementsv1. From what I see, that's all this spec needs.
(Maybe? I'm not an expert in the browser to understand this piece yet) patterns like
@tomdale brought up a great question about what and why the platform objectives.
Connecting to https://github.com/TheLarkInn/unity-component-specification/issues/1#issuecomment-320394137
This issue will discuss: Why should the platform support SFC as a format or module type? What would the platform be responsible for?