Front-end boilerplate for the web platform with Deno.
Includes
- Web component generator with lit-html and haunted
- PWA manifest and service worker generator (WIP)
- Redux boilerplate generator (WIP)
Notes
This boilerplate is still a work in progress...
Project requires deno and velociraptor to be installed
Custom element names require a hyphen (see using custom elements). Change this during setup (default:
x
)
Clone the repository and give the project a name
git clone [email protected]:shinobi5/skeletor.git <project-name>
Initialise new git repository
cd <project-name> && rm -rf .git && git init
Setup project
vr setup
Serve the project at localhost:1234
vr start
Create build for production in the root of the project at build/
vr build
vr create-component
<head>
<script
type="module"
src="js/components/custom-component/custom-component.js"
defer
></script>
</head>
<body>
<x-custom-component>Custom component</x-custom-component>
</body>
import { component, html } from 'https://cdn.skypack.dev/haunted';
import '../custom-component/custom-component.js';
const app = () => {
return html`
<x-custom-component>Custom component</x-custom-component>
`;
};
customElements.define('x-app', component(app, { useShadowDOM: false }));
For web components, styles can be set within the shadowDOM and will be encapsulated within the component.
A framework agnostic CSS-in-JS solution like csz can be used to generate scoped styles for custom elements without a shadowDOM.
Alternatively create component scoped global styles with a convention like BEM and remove the need for JS to scope and load styles at runtime.
import { component, html } from 'https://cdn.skypack.dev/haunted';
import css from 'https://cdn.skypack.dev/csz';
const customElement = () => {
return html`
<div class=${
css`
color: rebeccapurple;
background-color: black;
padding: 20px;
`
}>
Custom element with scoped runtime generated styles!
</div>
`;
};
customElements.define('x-custom-element', component(customElement, { useShadowDOM: false }));
Basic global styles are provided by default (but can be disabled through the setup CLI) with tools to watch for changes and concatenate the individual files into a single minified styles.css
.
The concatenating happens in order from broad to specific styles based on the folder they're in (in the following order): settings, global, elements, components, utilities
.
Haunted provides internal component state management (same as react hooks).
Global state can be handled with redux and boilerplate files can be generated through the setup step or by running:
vr create-redux
Routing examples using router-component.
<head>
<script src="https://cdn.skypack.dev/router-component"></script>
<script src="js/components/firstPage/firstPage.js"></script>
<script src="js/components/secondPage/secondPage.js"></script>
<script src="js/components/pageNotFound/pageNotFound.js"></script>
</head>
<body>
<router-component>
<x-first-page path="^/(index.html)?$"></x-first-page>
<x-second-page path="second-page"></x-second-page>
<x-page-not-found path=".*"></x-page-not-found>
</router-component>
</body>
import { component, html } from 'https://cdn.skypack.dev/haunted';
import 'https://cdn.skypack.dev/router-component';
import '../firstPage/firstPage.js';
import '../secondPage/secondPage.js';
import '../pageNotFound/pageNotFound.js';
const app = () => {
return html`
<router-component>
<x-first-page path="^/(index.html)?$"></x-first-page>
<x-second-page path="second-page"></x-second-page>
<x-page-not-found path=".*"></x-page-not-found>
</router-component>
`;
};
customElements.define('x-app', component(app, { useShadowDOM: false }));
Bundling is not really a thing in Deno (yet) so the best option seems to be a full-scale native es module approach (which is a good thing in my opinion anyway).
Deno has a bundler that works out of the box but it's not at all suitable for production builds. The resulting frontend SystemJS bundled file produced by the internal bundler is massive (lots of module loader boilerplate and no tree-shaking).
This is a great starting point for exploring how browsers handle es modules:
https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/
Deno bundling v3:
denoland/deno#4549
Possible option for bundling:
https://github.com/denofn/denopack