WebMake is an experimental TypeScript -> HTML module compiler. It works by allowing you to embed an HTML document in your TypeScript modules, thanks to JSX. The detection of an embedded document will signal to the compiler to invert the code for the module by compiling the remaining TypeScript source code and placing the resulting JavaScript inside of a <script type="module">
tag within the document. Sounds complicated, but it's absolutely not! Just take a look at the example below.
Input: TypeScript Module
import './custom-button'
<html lang="en">
<template id="index-page">
<section>
<header>
<h1>
Header
</h1>
</header>
<article>
<custom-button>
Lorem ipsum dolor sit amet...
</custom-button>
</article>
</section>
</template>
</html>
export class IndexPage extends HTMLElement {
#template = import.meta.document.getElementById('index-page') as HTMLTemplateElement
public constructor() {
super()
}
}
customElements.define('index-page', IndexPage)
Output: HTML Module
<!doctype html>
<html lang="en">
<template id="index-page">
<section>
<header>
<h1>Header</h1>
</header>
<article>
<custom-button>Lorem ipsum dolor sit amet...</custom-button>
</article>
</section>
</template>
<script type="module">
import "/src/custom-button";
export class IndexPage extends HTMLElement {
#template = import.meta.document.getElementById("index-page");
constructor() {
super();
}
}
customElements.define("index-page", IndexPage);
</script>
</html>
There are a few key proposals that I've got my eyes on:
As web developers, we've decided to go the JS-first route, which opened a ton of doors for us, but my interpretation of where I think the platform is headed is more of an HTML-first approach. However, if we attempt to only write raw HTML modules, we lose the ability to write type-safe code with TypeScript. With this tool you'll be able to write type-safe code that will compile into fully web-compatible modules.
While some of these proposals are a good ways off from being implemented, I intend to keep this tool up to date with the current direction of the specifications. The usefulness of this tool banks almost entirely on HTML modules, though, so that must be implemented before this tool can be taken seriously.
Since HTML modules are not implemented by any browser yet, WebMake allows you to compile your modules to regular JavaScript as well. More information coming soon.
WebMake will support bundling and code splitting in the form of Web Bundles.
WebMake treats most web-compatible resources as first class modules.
import main, { secondary, tertiary } from './another-module'
As per the TypeScript compiler, you may import JS & TS modules containing JSX markup.
import layout from './layout.html'
Importing an HTML document will result in a Document | DocumentFragment
containing the DOM elements.
import layoutStyle from './style.css'
Importing a CSS file will result in a CSSStyleSheet
containing the style rules.
import boxIcon from './icons/box.svg'
Importing an SVG document will result in an XMLDocument
containing the SVG elements.
It's not clear how useful additional module types would be yet.
- Images?
- Media?
- PDF?
Compiler was just rewritten to be more functional, documentation is a WIP. The following code produces a single WBN file from multiple modules and static files:
import * as WebMake from 'webmake'
async function webmake(index: string, outputConfig: WebMake.OutputConfig): Promise<WebMake.WebBundle> {
const project = {
app: await WebMake.readConfig(),
pkg: await WebMake.readPackageConfig(),
tsc: await WebMake.readTypeScriptConfig(),
out: outputConfig
}
const staticFiles = await WebMake.importStaticFiles(project)
const indexModule = await WebMake.importIndexModule(project, index)
const codeModules = await WebMake.compileModuleTree(project, indexModule)
return WebMake.createWebBundle(project, staticFiles, codeModules)
}