Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sprockets does not respect the filename extension I specified in link_directory (manifest.js) in ambiguous cases #796

Open
mildred opened this issue Nov 15, 2023 · 0 comments

Comments

@mildred
Copy link

mildred commented Nov 15, 2023

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 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant