Intro to web-component-boilerplate * by Dan McKeown
- altaredwood.work * 7/22/2020
The creators of Snowpack have created a command-line tool not unlike create-react-app but for web components called create-snowpack-app. This means that instead of using the React framework and its libraries to scaffold out your site, it gives you a choice of alternative tools and scaffolds out a component-based site using those frameworks. One of its options is Preact, a lightweight library with a similar API to React.
All these tools are very useful for staring out a component-based site. So where is the need to web-component-boilerplate? The basic answer is that web-component-boilerplate is even simpler than create-snowpack-app. It doesn't require a build step, it has only one flavor (Preact), and is designed to be very simple even for newer developers.
So how is web-component-boilerplate set up? First, it starts with an 'index.html' file at the root of the site. This file has standard HTML file boilerplate code and also these two key lines in the body:
⟨main id="main"⟩⟨/main⟩
⟨script type="module" src="/src/index.js"⟩⟨/script⟩
The first line declares a main element with id main. The second line references a JavaScript file in the src directory called index.js. This allows the code in index.js to run on this page--and due to the module type declaration we can safely know it won't run until the page's HTML has already loaded. Now let's take a look at the index.js file:
import ﹛ h, Component, render ﹜ from "/web_modules/preact.js";
import htm from "/web_modules/htm.js";
import App from "./app.js";
import Hammerhead from "./hammerhead.js";
const html = htm.bind(h);
class Index extends Component ﹛
render() ﹛
return html`
⟨$﹛App﹜ /⟩
⟨$﹛Hammerhead﹜ animal="Mango the Quaker Parrot" /⟩
`; ﹜ ﹜
render(
html`
⟨$﹛Index﹜ /⟩
`, document.getElementById("main") );
⟨script type="module" src="/src/index.js"⟩⟨/script⟩
Lines 1 and 2 load in our DOM library preact and our template library htm. Preact loads the Component object that is the base class for our component declaration, the render object which allows the creation of a 'render method' for declaring markup code via the htm library which is a function which uses the tagged templates pattern to transform the imported components App and Hammerhead into html. The h object is the hypersrcipt object that binds to the htm object. The render method, after the html function (the first parameter of which is the Index component, declared as a function inside an ES6 template string inside of angle braces), takes a second parameter which answers the question, where does all this code go once it is rendered? Here we see the main element again--since the page that this component is called from (index.html in this case) contains that element, the content should be rendered inside of that main#main element. Each of pages, app.js and hammerhead.js, have their own content that is combined on the Index page. But this is just a simple starter. Practically speaking, any number of components can be used side-by-side, or within parent-child hierarchies for any number of generations, or both at the same time. What is key is organized the site effectively for how it will be used. For information on setting up your own development site, check the QuickStart section of the project readme.