1

In a new Rails project I want to include some downloaded library js files that are already minified and usually only via script tag included in a web project. They are NOT modules.

I tried to use the importmap feature in Rails 7, but it destroys the library, making it unrunnable and throwing exceptions, because it is not a module. Is there a way to include in importmap the JS files of (minified) libraries that are without module system and do not wrap or modify them in any way?

My only way to get it working, was to put the JS file in public/js/library.js and add another script tag in the application layout.

But I expect that there is a easy standard way that includes my third party JS in some specified directory automatically NOT as modules and i need not to put each into public and source it inside my application layout. Furthermore a option to put them into one single file (and even minify it afterwards), would be the cherry on the cake.

magynhard
  • 158
  • 7

1 Answers1

1

If the library doesn't work when you import it with the use of import-maps, you can still use sprockets directives.

.
├── app/
│   └── assets
│       └── javascripts                       # <= create these
│           └── do_not_name_me_application.js # <=
└── vendor
    ├── javascript
    └── javascripts                           # <=
        ├── goodbye_library.js                # function bye(text) { console.log(text) }
        └── hello_library.js                  # function hi(text) { console.log(text) }
// app/assets/config/manifest.js

//= link do_not_name_me_application.js
# config/initializers/assets.rb

Rails.application.config.assets.paths << Rails.root.join("vendor/javascripts")
// app/assets/javascripts/do_not_name_me_application.js

//= require_directory ../../../vendor/javascripts

hi("loaded non module");
bye("also loaded");
# app/views/layouts/application.html.erb

<%= javascript_include_tag "do_not_name_me_application" %>

Test:

>> require "open-uri"
>> puts URI.open("http://localhost:3000/assets/do_not_name_me_application.js").read
function bye(text) { console.log(text) };
function hi(text) { console.log(text) };

hi("loaded non module");
bye("also loaded");

https://github.com/rails/sprockets#directives

Alex
  • 16,409
  • 6
  • 40
  • 56
  • 1
    Thank you, works perfect as i needed. There was only one "../" to much for require_directory. And by default the javascript folders in Rails are in singular instead of plural. Additionally I used require_tree instead of require_directory to include all files there recursively, without the need to add every folder explicitly. – magynhard Jul 31 '23 at 13:58
  • @magynhard `app/javascript` is for `node` or `importmaps`. `app/assets/javascripts` is for your regular js. also `vendor/javascript` is used by `importmaps-rails` when using `--download` option. don't mix the two or you might end up pinning or compiling or loading things twice. – Alex Jul 31 '23 at 16:40
  • thank you very much for your additional explanation! – magynhard Aug 01 '23 at 18:03