I am trying to import an image from JS in production. I have rails 6 with esbuild
and jsbundling
, and it works fine in development environment, but in production, images being imported from JS has no fingerprint. I've seen a Stack Overflow post like this one (Specific Image Not Loading After Rails 7 ESBuilt Update), but their solution was to move those image files to public/images folder. It's a solution, but this requires changing all JS files to load from a different location....
esbuild.config.js
const path = require('path')
require("esbuild").build({
entryPoints: ['app/javascript/application.js'],
bundle: true,
tsconfig: path.join(process.cwd(), "tsconfig.json"),
outdir: path.join(process.cwd(), "app/assets/builds"),
absWorkingDir: path.join(process.cwd(), "app/javascript"),
watch: process.argv.includes("--watch"),
incremental: process.argv.includes("--watch"),
assetNames: "[name]-[hash].digested",
publicPath: "/assets",
plugins: [],
loader: {
".js": "jsx",
".locale.json": "file",
".json": "json",
".png": "file",
".jpeg": "file",
".jpg": "file",
".svg": "file",
}
}).catch(() => process.exit(1))
Importing Image, where JavaScript file is under app/javascript/
, and image directory is app/javascript/images
.
import Logo from './images/logo.svg';
Logo file in app/assets/builds
in development
➜ work git:(master) ls -la app/assets/builds/logo*
-rw-r--r-- 1 yang staff 4710 Jun 26 16:30 app/assets/builds/logo-M5AMKDMO.digested.svg
Logo file referenced in HTML after the page was rendered in DEVELOPMENT
<img class="logo" src="/assets/logo-M5AMKDMO.svg">
Logo file in public/assets
in production
-rw------- 1 u18958 dyno 4710 Jun 24 02:48 public/assets/logo-M5AMKDMO.digested-abddddc51310100c173ac88db35b27e1492e730c91cb447b346f772532ac85ba.svg
Logo file referenced in HTML after the page was rendered in PRODUCTION
<img class="logo" src="/assets/logo-M5AMKDMO.svg">
The img tag in production is totally missing the fingerprint by asset precompile. The server is deployed in Heroku, and they do precompile during deployment.
One more thing: I did one test by setting config.assets.compile
to true
, and that actually worked, but you shouldn't do that per this post (config.assets.compile=true in Rails production, why not?), so I feel quite stuck.
I'm guessing you have an old version of sprockets.
v4.1.0
is when.digested
thing works properly:I'm not sure how you're getting
/assets/logo-M5AMKDMO.svg
path, with this config it should be/assets/logo-M5AMKDMO.digested.svg
.That's the url generated by esbuild, it doesn't change in different rails environments.
.digested
is a recent addition, it's meant to skip the extra sprockets digest:You can also just rename files after precompilation: