1

In my Rails 7 project I have been using importmap for importing JS modules. here is the config:

# config/importmap

pin "application", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin_all_from "app/javascript/controllers", under: "controllers"
pin_all_from "app/javascript/lib", under: "lib"
pin "@yaireo/tagify", to: "@yaireo--tagify.js" # @4.26.5
pin "@simonwep/pickr", to: "@simonwep--pickr.js" # @1.9.1

JS directory looks like this (app/javascript):

├── javascript
│   ├── application.js
│   ├── controllers
│   │   ├── file1.js
│   │   └── file2.js
│   └── lib
│       ├── file3.js
│       └── file4.js

in asset.rb I've also included these:

Rails.application.config.assets.precompile += %w( lib/file3.js )
Rails.application.config.assets.precompile += %w( lib/file4.js )
Rails.application.config.assets.precompile += %w( controllers/file1.js )
Rails.application.config.assets.precompile += %w( controllers/file2.js )

And app/javascript/application.js looks like this (maybe here is the problem):

import { Turbo } from "@hotwired/turbo-rails"
Turbo.start();

import { Application } from '@hotwired/stimulus';
import File1Controller from './controllers/file1.js'
import File2Controller from './controllers/file2.js'


const application = Application.start();
application.register('file1', File1Controller);
application.register('file2', File2Controller);

And lastly app/assets/config/mainfest.js looks like this:

//= link_tree ../images
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link_tree ../builds

All working great in development on localhost but it production it's showing:

Loading module from “https://mysweet.domain/assets/controllers/file1.js” was blocked because of a disallowed MIME type (“text/html”).

How could I resolve it?

4
  • Open up the network tab in the web inspector in the browser. You should be able to see the requests to load the JS files. What I suspect may be happing is that you're hitting an error page instead.
    – max
    Commented Jun 15 at 10:43
  • @max thanks for your prompt response. I found bit strange in network tab. there are actually 2 requests 1. is for file1-<something>.js (responding good) and 2. file1.js (which is failing)
    – rony36
    Commented Jun 15 at 10:50
  • I don't really understand why you have both files in lib and javascripts with the same name.
    – max
    Commented Jun 15 at 10:54
  • @max not sure I understood you correctly - in lib there are file3 and file4, and inside controllers there are file1 and file2. not same files
    – rony36
    Commented Jun 15 at 11:43

1 Answer 1

2

What happened to the default importmap set up from when you generated your app? I suggest you create a sample app and have a look.

... blocked because of a disallowed MIME type (“text/html”)

Because you're getting a 404 for this file.

You don't have to precompile every single file in assets.rb, this is already done in manifest.js:

// link_tree ../../javascript .js

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

Do not use relative imports './controllers/file1.js', this only works in development. Relative path does not match anything in your import-map, that means the request comes in for undigested /assets/controllers/file1.js this only works in development because sprockets is serving the assets and it can handle both digested and undigested urls. In production you have precompiled assets that can be fetched with a digested url only.

You have to use imports that will match your import-map:

$ bin/importmap json
{
  "imports": {
    ...
    "controllers/file1": "/assets/controllers/file1-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
    "controllers/file2": "/assets/controllers/file2-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
    "lib/file3":         "/assets/lib/file3-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
    "lib/file4":         "/assets/lib/file4-04024382391bb910584145d8113cf35ef376b55d125bb4516cebeb14ce788597.js",
  }
}
import File1Controller from 'controllers/file1'
import File2Controller from 'controllers/file2'
import File3Lib from 'lib/file3'
import File4Lib from 'lib/file4'

Turbo.start(); - No need for that, I don't know where you got that idea from.

1
  • you are just awesome man! Do not use relative imports made it work!
    – rony36
    Commented Jun 16 at 12:40

Not the answer you're looking for? Browse other questions tagged or ask your own question.