After posting the random faces example yesterday, I decided I realized I wasn’t happy with the code. Please don’t look at it. I’ll be porting it to TypeScript, which will require that I set up a build pipeline with Webpack.

I followed the tutorial here by Alli Zadronzny:

This involves moving all of the Jekyll files into a ‘src’ directory at the project root, except for the _config.yml file. You’ll need to add the following to that that file:

destination: public
source: src

This will tell Jekyll to build the files in source, and put the output in public.

In general, this also seems to be a more sensible directory organization as I also have a Dockerfile and other build scripts at the top-level. This directory layout removes the need to ignore so many files.

Next, sprinkle JavaScript via node at the top-level. This provides TypeScript compiler. I am following the examples here: TypeScript WebPack Setup

npm install --save-dev typescript ts-loader

Here’s the webpack.config.js I’m using. I may load different bundles into each blog post, so I name the entrypoints. It starts with code in ‘/webpack/hello.ts’ and builds output to ‘src/assets/js/hello.bundle.js’. This is primitive code splitting as described in WebPack Code Splitting, but it is enough for what I need here.

const path = require('path');

module.exports = {
  entry: {
  module: {
    rules: [
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
  resolve: {
    extensions: [ '.tsx', '.ts', '.js' ]
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'src/assets/js/')

I also added a “webpack” command to my ‘package.json’ so I can build things by running:

npm run build

During development, I can run

npm run watch

Here’s the package.json

  "name": "timestretch-blog",
  "version": "1.0.0",
  "description": "Timestretch Blog",
  "main": "./webpack/entry.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "watch": "webpack --watch"
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^5.3.3",
    "typescript": "^3.4.4",
    "webpack": "^4.30.0",
    "webpack-cli": "^3.3.0"

The text below is injected into the web page from TypeScript, built with WebPack: