sprockets does not respect the filename extension I specified in link_directory (manifest.js) in ambiguous cases
mildred opened this issue · 0 comments
Actual behavior
Given that I configure in an initializer Sprockets.register_mime_type 'application/javascript, extensions: ['.mjs']
and that I have a directory where two files share the same basename but with different extensions (one .js
and one .mjs
)
Currently, it is as if when I put in the manifest a directive like //= link_directory path/to file.mjs
, sprockets would strip the .mjs
extension and register that I want to link the directory path/to
and inside the file with the basename file
and an extension that match application/javascript
. But this is ambiguous and not what I specified.
Currently, in that circumstance, when I ask sprockets for the file path/to/file.mjs
it will instead serve me the file public/assets/path/to/file-HASH.js
, but the file content differs.
Expected behavior
When in app/assets/config/manifest.js
I reference a file, its file extension should be preserved even when there are multiple files with different extensions but the same content-type
System configuration
- Sprockets version 4.2.1
- Rails 7.1.2
- Ruby version 3.2.2
Example App (Reproduction)
I wish I could but I tried to create a new app wuith rails new
and sprockets fails out of the box with a "\xE2" to UTF-8 in conversion from ASCII-8BIT to UTF-8 to UTF-32LE (Encoding::UndefinedConversionError)
Reproducing the example should be easy from any app that is working:
-
yarn add use-bootstrap-select
(it contains the files that causes the issue -
add in
app/assets/config/manifest.js
the directive//= link_directory ../../../node_modules/use-bootstrap-select/dist use-bootstrap-select.mjs
-
optional: make use of it in the importmap (add in
config/importmap.rb
the linepin 'use-bootstrap-select', to: 'use-bootstrap-select/dist/use-bootstrap-select.mjs', preload: true
). This is to get the asset path easily. -
start the rails server
-
use
bin/importmap json
to get the asset oath for theuse-bootstrap-select.mjs
file, open it up in the browser served by rails and you'll get the file but with a content-type oftext/plain
. That's not ok, so let's try to fix this. -
in an initializer in
config/initialisers/assets.rb
add:{ '.mjs' => 'application/javascript' }.each do |ext, content_type| Sprockets.register_mime_type content_type, extensions: [ext] Rack::Mime::MIME_TYPES[ext] = content_type end
-
Restart rails, run
bin/importmap json
to get the asset path for use-bootstrap-select.mjs -
Open up the asset path in the browser, this time the content-type is correct but the file content is not
node_modules/use-bootstrap-select/dist/use-bootstrap-select.mjs
but isnode_modules/use-bootstrap-select/dist/use-bootstrap-select.js
. The incorrect file is served
edit: by the way it would be great if there was a working example app we could fork to demonstrate the issues.