This site’s build process is orchestrated by a Makefile and involves executing a TypeScript program for some of the nitty-gritty (for example, building the page with all posts and doing some HTML post-processing).
A Makefile (or similar build system) is nice when doing development or drafting posts so that I can only re-build the parts of the site that need to be built. I want to include the TypeScript build (tsc -p util) in the Makefile so that I have a single step and source-of-truth for the build. I hadn’t found anyone who’d written up how they’d incorporate a TypeScript project into a Makefile1 so I thought I would put my approach in to words.
My TypeScript helper project is in the util sub-folder of my repo, and I want the project to be as standard as possible to make it easier to use VS Code (or any other tooling) for editing - so it has a package.json and a tsconfig.json which are pretty standard.
Sometimes when I’m editing the TypeScript files I’ll remember to kick off the compiler in watch mode, but sometimes I don’t and I’d like to make sure that when I run the build for my site as a whole it runs the TypeScript compiler when it needs to.
My TypeScript utility has a single entry-point - util/out/index.js.2 I can give this output a target in my Makefile which invokes tsc:
utilJs := util/out/index.js
# Builder helper utility
$(utilJs): $(utilSources)
$(tsc) -p util
Then, every other target which would invoke my utility gets a dependency on the single entry-point. For example:
util := node --use-strict $(utilJs)
# Generate listing of all posts
$(site_working)/content/posts.md: $(database) $(utilJs)
$(@D)
mkdir -p $(util) all-posts $< $@
(Here, $(database) is our index of all posts, including its posted-on date, which we consume to make posts.html)
To make sure we’re re-building the utility whenever its sources change we also need to fill-out the $(utilSources) variable used above:
utilSources := ${shell find util/src -type f}
We also make sure we’re using the project-local version of TypeScript:
tsc := util/node_modules/.bin/tsc
I am not tracking changes to packages.json, tsconfig.json, or anything in the node_modules folder - my Makefile assumes that node_modules are installed properly but don’t do anything to track that that is happening correctly.
This matches the sorts of development I’m doing most often and I don’t have to figure out how to fit npm install correctly in to a make workflow.
I do have some helper targets in the Makefile to do npm tasks, but they aren’t used by any other targets:
node-modules-install:
(cd util && npm install)
node-modules-clean:
rm -rf util/node_modules
(That is, make clean does not include the node-modules-clean target.)
I’m not sure how I looked, because it’s pretty easy to find people talking about it when I search now. For example, this example might be better than what I’m writing up here↩︎
“out” is the outDir in my tsconfig.json↩︎