HTML templates in webpack
This article chronicles a small part of my journey towards creating a full website that can be rendered in three parallel frameworks and three parallel design systems (React + Material UI; Angular + Clarity; “Vanilla” JS + Carbon).
← Previous article: Jest, Typescript, and unit testing
→ Next article: A new structure for my single page application
To this point, I have intentionally built my site entirely in Typescript, including building and rendering content. While this works well to practice a pattern, explore a technique, or to prove a point, it isn’t a great long-term solution. HTML templates are much easier to read, faster to write, and much simpler to edit.
Thankfully, Webpack can be configured to handle HTML templates. What’s more, they can then be imported directly into Javascript or Typescript files, in which a template’s content will be treated like a string:
This makes it easy to insert the templates into a DOM element using the HTMLElement.innerHTML
attribute.
The configuration was pretty straightforward. I installed webpack’s html-loader
…
npm i -D html-loader
… And then added a rule to for handling HTML files to webpack.config.js
:
module: {
rules: [
{
test: /\.html$/i,
loader: 'html-loader',
},
...
],
},
For Typescript, I added a simple type definition so it would treat HTML template imports as strings:
html.d.ts
=========declare module '*.html' {
const value: string;
export default value;
}
With setup complete, I was able to refactor my view make__View()
functions as HTML templates:
You can view both the original Typescript code and the HTML template on GitHub.
Not only did this refactor remove all my Typescript make__View()
functions, it allow me to remove almost all my view utility functions. In fact, pretty much the only remaining Typescript code related to navigation… and that section still looks pretty ugly.
After a few rounds of incremental refactoring, I was able to clean up my navigation handling code. Transitioning to HTML templates made the rendering functions simpler, and I moved the navigation configuration to a separate file:
View the navigation.config.ts file on GitHub.
The navigation handling still wasn’t where I would like it to be, but I decided to leave it as is, for now. In fact, I plan to re-architect it shortly; it’s a larger project, but it means the current setup will be a temporary one.
This piece of work didn’t add any new functionality; it merely refactored and simplified existing functionality. But, in doing so, I managed to significantly clean up the code base, removing quite a bit of code in the process. A clean up project is a good project.