TL;DR.
- Sprockets 4 isn't loading javascript assets properly from a Rails 7 engine.
Project Overview
I am working on a Rails project, which is comprised of a
parent-appandengine-app.Both have been upgraded to
rails (~> 7.0.8)fromrails (~> 5.x).Both are now using
sprockets (~> 4.2.1)andsprockets-rails (~> 3.4.2).NOTE: We chose to maintain using
sprocketssince it's a large production application already in use and would be too costly for us to port over to the new way of managing assets at this time.The
parent-appis almost bare bones. Most business logic, UI, and assets are within theengine-app.
manifest.js
Sprockets 4 now requires a manifest.js to determine which top-level targets to compile (documentation).
parent-app
In parent-app, I created just such a file. Its contents are straightforward.
// file: parent-app/app/assets/config/manifest.js
//= link_tree ../images
//= link application.js # has one line of code: `//= require_tree .`
//= link application.sass # has one line of code: `@import engine_app/application`
//= link engine_app_manifest.js
engine-app
In engine-app, I created a similar file with a different name. The name of the manifest.js in the engine can be anything from what I've gathered. This is based on information I gathered from the following SO posts:
- How do I tell Sprockets 4 to compile assets for a vendored gem?
- Sprocket Rails V4 link to manifest files of external gems
// file: engine-app/app/assets/config/engine_app_manifest.js
//= link_tree ../fonts/
//= link_tree ../images/
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
link_directory ../javascripts
There are several .js files in this directory that require other javascript. The most important of which is application.js. Here's a snippet.
// file: engine-app/app/assets/javascripts/application.js
//= require babel/polyfill
//= require jquery
//= require jquery_ujs
//= require jquery-ui
//= require jquery.remotipart
//= require smart_listing
//= require underscore-dev
// ... and more
alert("HELLO WORLD!"); // added this to test if its being loaded
Results
Based on the SO posts referenced above, this is all that should be needed to load assets from a vendor gem or engine, but it seems not only to work partially. The stylesheets from the engine-app seem to be loaded as the UI looks as it should. However, the javascripts are not.
There are Uncaught ReferrenceErrors being thrown and reported in the console. The alert message isn't being shown either. And when I look at the source files loaded using Chrome's DevTools, there are only a few files.
Contrast this to what's being loaded in the legacy app.


You can use sprockets directives in main app application.js:
or load it directly, in this case this file has to be precompiled as well:
linkandrequiredirectives take asset name as an argument relative toRails.application.assets.paths.Your main issue was the use of
modulescripts, which changes the load order of the script:Installation instructions for
i18n-jsdon't require a module:https://github.com/fnando/i18n-js/tree/v3.9.2?tab=readme-ov-file#rails-app-without-asset-pipeline
Also, note that you can add
type="module"to any script tag if needed: