I think the only problem with your current setup is the name of the files. When dune creates a javascript file using (modes js) it gets the extension .bc.js which is what you need to depend on for the preprocessor i.e.
ppx_blob is good for a single file, but I’ve found ocaml-crunch to be easier to work with, since it can scoop up a whole directory (e.g. a set of static web assets) and provide you with those files via a convenient lookup module. n.b. the dune example in its repo that shows how to set up a rule for regenerating the lookup module when the target directory’s contents change: ocaml-crunch/dune at master · mirage/ocaml-crunch · GitHub