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 line pin '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 the use-bootstrap-select.mjs file, open it up in the browser served by rails and you'll get the file but with a content-type of text/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 is node_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.
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 directorypath/to
and inside the file with the basenamefile
and an extension that matchapplication/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 filepublic/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-typeSystem configuration
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 issueadd 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:Restart rails, run
bin/importmap json
to get the asset path for use-bootstrap-select.mjsOpen 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 servededit: by the way it would be great if there was a working example app we could fork to demonstrate the issues.