Web development: back to basics
update: 20211230 - i found webcomponents!
Here's my current throughts about what makes the web so hard and complicated to work with
This post is inpired by this talk by Stuart Langridge
One of the main points of the talk is: Simplicity, and Control
Why is the web so complex?
bundlers are a great example...
Stuart Langridge points out that the current reasons are good ones but they are all self justifiing on a pirmid of simple statements.
He uses a good old days framing to talk about it. but his underlying main point is solid: the web is not a compile target, but a platform of standards use them.
But making something look good currently everything is built around the it must have javascript mindset
Possible fixes
aka things id like the web to have
builtin component system
ive been playing around with svelte resently and i like the back to basics approce to formating the components
EX:
<CustomButton />
Code:
<script>
Code goes here
</script>
<main>
<!-- html markup goes here -->
</main>
<style>
your styling goes here
</style>
Code reuse like this
import CustomButton from "CustomButton.svelte"
<h1> My awesome website</h1>
<CustomButton> Click Me </CustomButton>
Id like to change this slightly to be more like this
import CustomButton from "https://<path-to-cdn>.com/custombutton"
<h1> My awesome website</h1>
<CustomButton> Click Me </CustomButton>
This is something that deno uses
import { assertEquals } from "https://deno.land/[email protected]/testing/asserts.ts";
assertEquals("hello", "hello");
assertEquals("world", "world");
console.log("Asserted! ✓");
The goal and difference here is to have no bundlers, just web standards javascript
Hurdles:
- Es6 modules importing like this dont currently work
- CORS
- state management
The fix
...kinda
Webcomponents
a amazing (and importantly: borning) step forward in web development
After writing the first draft of this article I ran accross webcomponents
what are webcomponents
?
webcomponents are not a new javascript framework but just a set of 4-ish webstandards that enables compontization of reusable code, that is afterall the promise of libraries like react, vue, svelte
what browser features makes up webcomponents?
1) Custom Elements
<my-awesome-button name="clickme"></my-awesome-button>
2) Shadow DOM : css style isolation
shadow dom is a way to isolate css styles of your component from effecting the rest of your page
3) ES Modules
import "https://example.com/module.mjs";
4) HTML Templates
const template = document.createElement('template').innerHTML = `
<button id="toggle-info">hide info</button>
`;
<script>
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector("button").innerText = "show info";
</script>
here we are creating a html template, i think they are basically like JSX (react's answer to html within javascript )
Examples
html templates Slots
:
this is a advanced feature but its really great to see it implemented into the browser
this is something that is part of svelte, and react. slots are a pattern for allowing nested components in the dom
lets look at a slots
example
/index.html
<contact-info>
<div slot="email"> 我吃[email protected]</div>
<div slot="phone"> 555-555-5555</div>
</contact-info>
..sniped..
let template = `
<p>
<slot name="email"/>
<slot name="phone"/>
</p>
`
...sniped.
Full example
<html>
<body>
<user-card>
<div slot="email"> [email protected]</div>
<div slot="phone"> 555-555-5555</div>
</user-card>
<script>
class UserInfo extends HTMLElement {
constructor() {
super();
let template = `
<p>
<slot name="email"/>
<slot name="phone"/>
</p>
`
let html_template = document.createElement('template').innerHTML = template
this.shadowRoot.appendChild(html_template.content.cloneNode(true));
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
window.customElements.define('user-info', UserInfo);
</script>
</body>
</html>
Webcomponent argument example
<html>
<body>
<!-- custom components passing in propterites -->
<user-info name="John Doe"></user-info>
<user-info name="Bily bob"></user-info>
<user-info name="Jane Smith"></user-info>
<script>
const template = document.createElement('template');
template.innerHTML =`<button> </button>`
class UserInfo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector("button").innerText = this.getAttribute("name");
}
}
window.customElements.define('user-info', UserInfo);
</script>
</body>
</html>
take note of <user-info name="John Doe"></user-info>
the 'name' prop is similar to react props
getting that to work is actually kinda annoying
//1) create a html template
const template = document.createElement('template');
template.innerHTML =`<button> </button>`
//2) setup vertual dom to use html template
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
//3) use `querySelector` to modify the dom element
/// this one is interesting this.getAttribute is the equivalent in react to UserInfo({name}){} which is cool
this.shadowRoot.querySelector("button").innerText = this.getAttribute("name");
how to use webcomponets
or my learnings for playing with them for a bit
Throughts on webcomponents
its still evolving...
Current browser support
its pretty good for evergreen browsers
Overall:
great start
, but is currently really boilerplat-y, and could benifit form a simpler api, good building blocks, currently not not easy to use
what its missing:
- statemanagment
- reactivity
- import-maps (allows for npm module loading in a sain way)
- WICG/import-maps: How to control the behavior of JavaScript imports
I see webcomponents as a trend to want to get back to the basics of webdevelopment, and let bundlers do what their good at bundling. not a making them a requirement for everyting in web dev
Read more cool stuff!
Recommended posts:
Author
by oran collins
github.com/wisehackermonkey