openlawteam/openlaw-client

repeat build performance of build:esm phase

Opened this issue · 0 comments

mroth commented

Encountered this separately while working on the other build stuff, carving out as a separate issue to remind myself for the future.

Currently the build:esm phase (which is prerequisite of running release) is defined via npm scripts such as:

  "scripts": {
    /* snip */
    "build:esm": "npm run build:esm:apiclient && npm run build:esm:openlaw && npm run build:esm:index",
    "build:esm:openlaw": "npx cpy --rename=openlaw.js 'target/scala-2.12/client.js' 'dist/esm/lib/' && npx terser dist/esm/lib/openlaw.js -cm --module -o dist/esm/lib/openlaw.js",
    "build:esm:apiclient": "npx cpy --rename=apiclient.js 'js/src/APIClient.js' 'dist/esm/lib/' && npx babel dist/esm/lib/apiclient.js -o dist/esm/lib/apiclient.js && npx terser dist/esm/lib/apiclient.js -cm --module -o dist/esm/lib/apiclient.js",
    "build:esm:index": "npx cpy --rename=index.js 'js/src/index.esm.js' 'dist/esm/lib/'",
    /* snip */
  },

The disadvantage of this method is there is no awareness of what files have already been built and are up to date, thus every time the phase is invoked the entire thing re-runs whether or not the dependencies have changed.

Replicating the same via a standard Makefile enables only changed files to need to be rebuilt, and for jobs to be run in parallel.

Example Makefile (yeah, I know I like using variables...)

ESM_LIB=dist/esm/lib
JS_SRC=js/src
SCALA_TARGET=target/scala-2.12

build_esm: ${ESM_LIB}/openlaw.js ${ESM_LIB}/apiclient.js ${ESM_LIB}/index.js

${ESM_LIB}/openlaw.js: ${SCALA_TARGET}/client.js ${ESM_LIB}
	npx terser $< -cm --module -o $@

${ESM_LIB}/apiclient.js: ${JS_SRC}/APIClient.js ${ESM_LIB}
	npx babel $< | npx terser -cm --module -o $@

${ESM_LIB}/index.js: ${JS_SRC}/index.esm.js ${ESM_LIB}
	cp $< $@

${ESM_LIB}:
	mkdir -p $@

Comparative benchmarks on my workstation

npm run build:esm make -j4 build_esm
initial build 31.6s 23.1s
change APIClient.js 31.6s 1.4s
no changes 31.6s 0.0s

(It's worth noting my workstation is fairly fast, and the actual numbers when run on our standard CI hardware are roughly double this, so the ratio difference becomes potentially more dramatic on a CI server or laptop.):

Note, I don't believe we should switch to a Makefile here, as currently this works via just NPM such that it doesn't matter if someone is on a Windows machine (which may not have Make installed). However, I strongly suspect there is a way to get JS build tools to do something similar.

We already have both webpack and rollup as a dev dependency here, so I'd be loathe to install yet another build tool. Perhaps one of them can handle it? Leaving this as notes for myself in the future to look into and tackle this!

CC FE folx (@jtrein @jdville03 @sophiacodes) if you know the best practice/tool here, feel free to drop some notes to help me out when I get around to this one day.