Hotwire not being found

Anyone able to help me fix why I’m getting this error when deploying to production only:

Uncaught TypeError: Failed to resolve module specifier “@hotwired/turbo-rails”. Relative references must start with either “/”, “./”, or “../”.

I’m including application.js like this:

<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true, type: "module" %>

application.js looks like:

// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import "./controllers";

I am NOT using importmaps. I’m using jsbundling-rails and esbuild. My ES build config is:

#!/usr/bin/env node

const path = require("path");
const watch = process.argv.includes("--watch");
const esbuild = require("esbuild");

const config = {
  absWorkingDir: path.join(process.cwd(), "app/javascript"),
  entryPoints: ["application.js", "avo.custom.js"],
  outdir: path.join(process.cwd(), "app/assets/builds"),
  chunkNames: "[name]-[hash].digested",
  bundle: true,
  minify: true,
  sourcemap: true,
  target: "es6",
  watch: watch
}

Would appreciate some guidance here.

Can anyone help with this issue?

I believe it’s similar to the problems I had with importmaps, so I’ll give it a try: In your config you could try to adjust

chunkNames: "[name]-[hash].digested"

to

chunkNames: "/assets/[folder]/[name]-[hash].digested"

which you might have to adjust individually for every file. I’m not familiar with this setting, so I can’t be more specific. Basically, in dev-env, Rails will “dig” through your code and find the respective module. On prod, though, it needs the exact location of the compiled module, which rests under “assets”. With importmaps I have to list every file individually to work on prod, so maybe it’s similar.

Just made that change and deployed. No change.

The weird thing is it’s been working for ages and i don’t think i’ve changed anything that would cause this.

It’s soooo weird.

When you look at the page source, what does the importmap show?

There is no import map. I am not using them.

The app is this by the way if you wish to take a look:

It would seem nothing but application.js is actually deployed/compiled. Again, not familiar with your setup. The files you’re importing must be bundled somehow, though.

Yes, it seems like application.js is not getting compiled.

It still shows as:

// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import "./controllers";
import "./parts/dropdown-navigation";
import "./parts/message-boxes";

Soooo confused as to why this is not compiling.

I gets compiled locally, just not in production.

As nothing has changed (truly nothing?) in your app, might there be something on your host or the way you deploy?

Can you see in production if your node_modules folder does contain @hotwired/turbo-rails? Because it should.

Still unsure what’s going on but heres some new information:

I did a fresh deploy and it errors. I check the public/assets directory and see application-50290509.js. This is the digest for the below. Ie: the non-compiled file.

// Entry point for the build script in your package.json
import "@hotwired/turbo-rails";
import "./controllers";
import "./parts/dropdown-navigation";
import "./parts/message-boxes";

If I run bundle exec rails assets:clobber to wipe out all the assets and then follow that by bundle exec rails assets:precompile, I check the file listing and now see application-39087e34.js which is the digest of the compiled version, ie: the file we want!

I check the app and look at the source where I see the script tag shows:

<script src="[/assets/application-50290509.js](https://neiltonge.co.uk/assets/application-50290509.js)" data-turbo-track="reload" defer="defer" type="module"></script>

Importing the wrong file (which now no longer exists).

What on earth is going on? Why is it failing to precompile that file correctly on deployment but can do it correctly when run manually? It also works fine in development and when I try to precompile locally too.

I have this on Digital Ocean deployed via @excid3 's Hatchbox. I’ve contacted Chris on there and he’s assurred me it’s not Hatchbox.

I’m now very confused as to what’s causing this to occur.

Appreciate any and all help!

Thanks, Neil

Yes it does. It’s in there.

I just cannot seem to figure out why the URL (https://neiltonge.co.uk/assets/application-50290509.js) works and returns a file when i’ve just checked on the server and that file does not exist at all. Only (https://neiltonge.co.uk/assets/application-39087e34.js) this file actually exists in the filesystem.

WHAT IS HAPPENING? I’m sooo confused. :face_with_spiral_eyes:

Do you have a .keep file within the app/assets/builds folder? You should otherwise it will not refresh your public/assets folder.

No I don’t. I didn’t think app/assets/builds was used in Production?

Any documentation for a .keep file?

Aha! Add the empty .keep file to your GIT repo. It will keep the empty builds folder with deployment. See e.g. You have to have an empty assets/builds folder in the repo · Issue #60 · rails/jsbundling-rails · GitHub (I found out the hard way myself)

1 Like

@javinto1 I LOVE YOU! If we ever meet in person, I owe you many beers!

Seriously, Thanks. This has been bugging me for days! Initial test seems like it’s the solution so i’ll do more checks and update in a day or two to confirm.

Really appreciate the help!

You’re welcome!!! Rails conference September Amsterdam maybe :wink: