ruby-on-railsruby-on-rails-7trixactiontext

Uncaught SyntaxError: The requested module 'trix' does not provide an export named 'default' (at youtube.js:1:8) in rails 7.1 when trying to edit trix


I am currently facing an issue when I try to configure the actiontext editor in rails 7.1.3 to handle YouTube videos embedded.

Currently running rails 7.1.3, ruby 3.2.0, and using importmaps.

(Following Chris Oliver's excellent example https://www.youtube.com/watch?v=2iGBuLQ3S0c There is a written guide here - https://dev.to/superails/ruby-on-rails-embed-youtube-videos-with-actiontext-tldr-3m35)

I am getting this error - Uncaught SyntaxError: The requested module 'trix' does not provide an export named 'default' (at youtube.js:1:8) The error is understandable, but I don't know how to fix it.

In my youtube.js file I import trix like this.

import Trix from "trix"
import Rails from "@rails/ujs" 

let lang = Trix.config.lang;
Trix.config.toolbar = {
  getDefaultHTML: function() {
    return `
    <div class="trix-button-row">
.....

I tried without luck to change it to

import * as Trix from "trix"

When I look into the trix.js, I do see an export:

export{Wn as default};

My importmap.rb looks like this:

Pin npm packages by running ./bin/importmap

pin "application"
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js"
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js"
pin_all_from "app/javascript/controllers", under: "controllers"
pin "@rails/actiontext", to: "actiontext.esm.js"
pin "@rails/ujs", to: "@rails--ujs.js" # @7.1.3
pin "trix" # @2.0.10

Has anyone experienced this issue before? And maybe found a solution?


Solution

  • pin "trix" links to a UMD build which doesn't have any exports, it only exposes Trix globally. That means import "trix" is all you need. This build is meant to work with plain sprockets as well:

    https://github.com/rails/rails/blob/main/actiontext/app/assets/javascripts/trix.js

    On the other hand, ESM build has a default export:
    https://cdn.jsdelivr.net/npm/trix@2.0.10/dist/trix.esm.js


    >> Rails.application.assets.find_asset("trix").filename
    => "/home/alex/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/actiontext-7.1.3/app/assets/javascripts/trix.js"
    

    If you've pinned trix separately into your vendor directory (which would be esm build), it won't change anything because vendor is all the way at the end of the assets paths:

    >> Rails.application.assets.paths
    => 
    ["/home/alex/code/stackoverflow/app/assets/builds",
     "/home/alex/code/stackoverflow/app/assets/config",
    ...
     "/home/alex/.rbenv/versions/3.3.0/lib/ruby/gems/3.3.0/gems/actiontext-7.1.3/app/assets/javascripts",
    ...
     "/home/alex/code/stackoverflow/vendor/javascript"]  # <= gets searched last
    

    This is the best I could figure out to fix the order:

    # config/initializers/assets.rb
    
    Rails.application.config.after_initialize do |app|
      # https://github.com/rails/sprockets/blob/v4.2.1/lib/sprockets/paths.rb#L37
      app.assets.prepend_path Rails.root.join("vendor/javascript")
    end
    
    >> Rails.application.assets.find_asset("trix").filename
    => "/home/alex/code/stackoverflow/vendor/javascript/trix.js"
    

    Changing your pin to jspm url also can fix this, however url pins are no longer a thing by default in importmap-rails v2, so this is a manual copy-paste operation:

    # config/importmap.rb
    
    pin "trix", to: "https://ga.jspm.io/npm:trix@2.0.10/dist/trix.esm.min.js"