Loop Supreme, part 8: Building and hosting
2022-11-18 11:39:14 +0000 UTCThis is part 8 in a series about building a browser-based audio live looper
- Part 12: v1.0 release, and project retro
- Part 11: Exporting stems and changing inputs
- Part 10: Keyboard bindings
- Part 9: Visualizing the waveform
- Part 8: Building and hosting
- Part 7: Latency and adding Track functionality
- Part 6: Workers and AudioWorklets
- Part 5: Record and loop a track
- Part 4: Adding a Scene
- Part 3: Metronome click
- Part 2: Adding a Metronome
- Part 1: New project: building a web-based audio looper!
Goal
Fix the build issue that was causing AudioWorkletProcessors
to fail to load. Host it somewhere.
Implementation
Fixing the build issue was the weirdest rabbit hole I’ve gone down. I could see that all the files were being put in the correct places, but for some reason the app was choking when trying to register the RecordingProcessor (an AudioWorkletProcessor
). This was written in plain JS so I couldn’t understand what the issue was. I tried converting it to TS but that threw an error too.
I finally inspected the built contents of the recorder.js
file in my build
directory, and immediately saw the problem. Due to a Webpack bug, the compiled file contained import
statements that referenced absolute paths on my local machine. Of course, the built files should be independently runable, so it made no sense to include hardcoded file paths to my local machine.
After reading a good chunk of the replies in the Webpack issue thread, I tried several of the recommended fixes, to no avail. I debated installing the worklet-loader
library, but it sounded like the Webpack team did not love this solution. I decided to keep to my project ethos of “dead simple & rough edges are OK”, and built a simple postbuild script that simply copies the JS file contents from the source file into the final file. This isn’t ideal because it isn’t minified, but it’s a fairly small file and this is a project site. We can optimize in the future. The other potential downside is that older browsers might choke on the “new” ES class syntax, but since most of the features in this app will fail in older browsers anyway, I decided it wasn’t worth my time to investigate.
The other big push was getting hosting set up with Cloudflare. I was really pleased how easy it was to get up and running. I think some of their wrangler
docs could be fleshed out, but they make it clear that the pages
commands are in beta so I’m willing to cut them some slack. If you’re launching your own site on Cloudflare Pages, there are 3 key things to do:
- Create your API Token with “Cloudflare Pages: Edit” permissions - found under the “Account” category. I missed this several times because the entries are alphabetical and I assumed it would just be called Pages (after all, everything is “Cloudflare”…). See screencap below
- Create your project with Wrangler before you publish:
wrangler pages project create my-project
, thenwrangler pages publish build -- --project-name=my-project
- Set your env vars correctly at the command line. It isn’t extremely well documented by you need a
CLOUDFLARE_API_TOKEN
andCLOUDFLARE_ACCOUNT_ID
env var declared when you run Wrangler. So the final command looks something like:
CLOUDFLARE_API_TOKEN=api-token \
CLOUDFLARE_ACCOUNT_ID=account-id \
wrangler pages project create my-project
CLOUDFLARE_API_TOKEN=api-token \
CLOUDFLARE_ACCOUNT_ID=account-id \
wrangler pages publish build --project-name=my-project
State of the app
- Merged PRs
- App can now build and deploy automatically
- App is hosted at loopsupreme.com (still working on the
www
subdomain redirect…) - A few styling updates
Next steps
- Add a waveform visualizer!