Javscript using importmaps not working looking for modules under assets

355 views Asked by At

I am trying to convert my rails 7 application using sprockets to use import maps because I was having issues using turbo and hotwire. I am not using bootstrap or tailwind. We are using materialize.

Im trying to import add custom files using Rails 7 import maps.

I am receiving an error in my console:

Uncaught TypeError: Failed to resolve module specifier "src".
Relative references must start with either "/", "./", or "../".

My tree is:

app
  javascript
      src
        custom.js
vendor
  javascript
    vendor_src
       .....

My importmap.rb contains:

....
pin_all_from "app/javascript/src", under: "src"
pin_all_from "vendor/javascript/vendor_src", under: "vendor_src"

My application.js contains:

import "src"
import "vendor_src"`

My manifest file is:

//= link_tree ../images
//= link_tree ../../javascript
//= link_tree ../../../vendor/javascript
//= link_tree ../stylesheets

When i change my application.js file to:

import "./src"
import "../../javascript/vendor_src"

(which the documentation says wont work in production) I now get the errors:

GET http://localhost:3000/vendor/javascript/vendor_src net::ERR_ABORTED 404 (Not Found)
application-1f36702eea04104593de68f423311c35ee03c50e8e8222ab5412a8a3674b03ef.js:2 

GET http://localhost:3000/assets/src net::ERR_ABORTED 404 (Not Found)

I ran bin/importmap json. This is what I get:

{
 "imports": {
    "application": "/assets/application-e61bcfe1fb2f267b11f0acff3d1ed2c1902e04e7916e87a411bb7f388cc63e7a.js",
    "@hotwired/turbo-rails": "/assets/turbo.min-dfd93b3092d1d0ff56557294538d069bdbb28977d3987cb39bc0dd892f32fc57.js",
    "@hotwired/stimulus": "/assets/stimulus.min-dd364f16ec9504dfb72672295637a1c8838773b01c0b441bd41008124c407894.js",
    "@hotwired/stimulus-loading": "/assets/stimulus-loading-3576ce92b149ad5d6959438c6f291e2426c86df3b874c525b30faad51b0d96b3.js",
    "src/custom": "/assets/src/custom-3497ac27760575852bfffaa55b4c5c424eb8db7864e90b39c9b7fd1113d41b78.js",
    "vendor_src/buttons.html5.min": "/assets/vendor_src/buttons.html5.min-ff801aa1b9b1c75fff4cbc8405aed63c1c5ba21ca7166a1dd763d2a3452e043d.js",
    "vendor_src/dataTables.buttons.min": "/assets/vendor_src/dataTables.buttons.min-66377feebbadf9480f9d8001dd24ed6229fa7cd0141f9637ec4b9953779615a3.js",
    "vendor_src/datatables-responsive": "/assets/vendor_src/datatables-responsive-dae0484f9a49d5c68366f086fe1935dd5f912722a3d4b6e19527a84a12719b78.js",
    "vendor_src/datatables": "/assets/vendor_src/datatables-3c7146355ec221e428330b38ecd5892f8afad44047ea4c74337710788f5c8683.js",
    "vendor_src/inputmask": "/assets/vendor_src/inputmask-0a843353ffd01e999ac94f7b4800ed17d08eb47886d0421bd2b55991584a922f.js",
    "vendor_src/jquery.dataTables.min": "/assets/vendor_src/jquery.dataTables.min-3c7146355ec221e428330b38ecd5892f8afad44047ea4c74337710788f5c8683.js",
    "vendor_src/jszip.min": "/assets/vendor_src/jszip.min-10aaae9e48e75307074d0b9b50d342d46f46517cc7370390359d6e8873cf7e1a.js",
    "vendor_src/materialize": "/assets/vendor_src/materialize-9b20e6a3f918ccdbf4faf5be1c79a293c31fa0be516e12e3acf97e13174ae354.js",
    "vendor_src/pdfmake.min": "/assets/vendor_src/pdfmake.min-e038e33bfbc05d2e97d36d9cd1b625e99eaad6e62f7ea69165a0eb1c59318e75.js",
    "vendor_src/vfs_fonts": "/assets/vendor_src/vfs_fonts-b799a394c53502034f3c3c4472da5c377c9a755a74f041fa5104660d009d6e66.js"
  }
}

Do I need to add all files individually in the application.js file?

Can someone please help?

2

There are 2 answers

0
Alex On

...use import maps because I was having issues using turbo and hotwire

Importmaps is how you import javascript modules in the browser. Turbo is just a javascript framework. You can use both without issues, it's the default setup in rails 7.

Do I need to add all files individually in the application.js file?

Yes, that would probably be simpler.


You can't import "src" or "vendor_src" because you don't have them in your importmap. You can add index.js files if you want to be able to import "directories":

// vendor/javascript/vendor_src/index.js

import "vendor_src/buttons.html5.min"
import "vendor_src/dataTables.buttons.min"
import "vendor_src/datatables"
import "vendor_src/datatables-responsive"
import "vendor_src/inputmask"
import "vendor_src/jquery.dataTables.min"
import "vendor_src/jszip.min"
import "vendor_src/materialize"
import "vendor_src/pdfmake.min"
import "vendor_src/vfs_fonts"
// app/javascript/src/index.js

import "src/custom"

Now if you run bin/importmap json you will have "src" and "vendor_src" which map to corresponding index files:

$ bin/importmap json
{
  "imports": {
...
    "src": "/assets/src/index-dfa1b5d0217643a14ef4b9bbea98e6373417cae7727f2dec8c363f532f02231b.js",
    "vendor_src": "/assets/vendor_src/index-852c266ac3e65f171a9a6ba2d8e036a0246afad24d6681233185147b79d1c294.js",
...
}

These imports should work now:

import "src"
import "vendor_src"

Also, don't use relative imports and in case you're unclear about what your imports can be:

>> puts JSON.parse(Rails.application.importmap.to_json(resolver: helper))["imports"].keys.map{%{import "#{_1}"}}
import "application"
import "@hotwired/turbo-rails"
...
0
Akeel Ahmed Qureshi On

In the Application.js file, you should import specific files or directories, not just the directories themselves.

Application.js

import "src/custom";
import "vendor_src/buttons.html5.min";

And Manifest file should include the correct relative path.

//= link_tree ../images
//= link_tree ../../javascript/vendor_src
//= link_tree ../../../vendor/javascript
//= link_tree ../stylesheets