I am working on a Rails project, which is comprised of a parent-app
and engine-app
.
Both have been upgraded to rails (~> 7.0.8)
from rails (~> 5.x)
.
Both are now using sprockets (~> 4.2.1)
and sprockets-rails (~> 3.4.2)
.
NOTE: We chose to maintain using sprockets
since 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-app
is almost bare bones. Most business logic, UI, and assets are within the engine-app
.
Sprockets 4 now requires a manifest.js
to determine which top-level targets to compile (documentation).
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
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:
// 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
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:
//= require engine_name/application.js
or load it directly, in this case this file has to be precompiled as well:
<%= javascript_include_tag "engine_name/application.js" %>
// link for precompilation in any of the manifest files
//= link engine_name/application.js
link
and require
directives take asset name as an argument relative to Rails.application.assets.paths
.
Your main issue was the use of module
scripts, which changes the load order of the script:
<script type="module">
// module scripts are deferred and loaded after the page is loaded
console.log("second")
</script>
<script>
console.log("first")
</script>
Installation instructions for i18n-js
don'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:
<script type="module">I18n.globals = {};</script>