Deploying JavaScript files, versioning and caching

I’m sure someone here has faced the following scenario:

I’m deploying and serving some web application with NixOS. Now and then, I want to update the application, which involves changes to both HTML and JavaScript files. Now it might well be that version 1 of the JavaScript files is incompatible with version 2 of the HTML files. So I want to avoid caching of the JavaScript files.

Independently of NixOS, some things to do to address this more or less reliably:

  1. add versioning query arguments to the script tags, e.g. src="js/main.js?v=2" or "main.js?<hash (of main.js, or full output, or git checkout)>"
  2. add versioning to the path, e.g. src="js/v2/main.js" or src="js/<hash>/main.js"
  3. do things to web server caching headers

(I may well be missing the right solutions here – not a frontend expert. Particularly, the web caching headers are a bit of a mystery to me at this stage.)

My question is, does anyone here have satisfying solutions for this using Nix/NixOS for deployment? I can manually patch in versioning à la 1. in a non-Nix-specific build step. (Full disclosure: I’m currently doing this, but on Guix. I’m planning to eventually migrate to NixOS though for reasons.)

But I’m wondering if there isn’t a nice way to get a version hash out of Nix and patch that in for version 1. Or ideally get variant 2 to work, by serving up several versions of the assets with a prefix. But that would require keeping several versions of a package around. (I’d rather not simply expose and link to the Nix store :slight_smile: .)

Or hopefully I’m overthinking this and there’s a better way? Any pointers appreciated!

  1. do things to web server caching headers

I think Nginx expression in Nixpkgs patches Nginx to support ETag based on the Nix store paths.

1 Like

This isn’t really a problem for nix to solve, is it? I think you should use a technology like webpack, or something like that.

1 Like

I was hoping to to avoid webpack. :confused:

On a more principled level, I find that working with Nix, it takes over the versioning side of things, and mixing this seems… messy.

But yeah, if webpack and friends is how folks do this, I’ll investigate. Thanks!

Edit:
Did a bit of webpack reading, compare Caching | webpack.

It seems that webpack (and other common asset versioning solutions) would generate versioned output files, but only for the current build input. They don’t deal with keeping old versions around; that would be the responsibility of the deployment tooling. I.e., still work to do for Nix if that’s what I use for deployment.