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

Does not appear to work in Rails 7 using import-map (new Rails default) #113

Closed
Merovex opened this issue Oct 28, 2021 · 15 comments
Closed

Comments

@Merovex
Copy link

Merovex commented Oct 28, 2021

Howdy, I'm building an app from scratch in Rails 7 Alpha. This uses import maps.

In the import map, I have pin "helpers/local-time", which works as expected. I can import the file no problem. I import thusly:

import "helpers/local-time"
import LocalTime from "helpers/local-time"

I get the following error:

SyntaxError: Importing binding name 'default' cannot be resolved by star export entries. 
http://localhost:3000/assets/es-module-shims.min.js

I know that's in the Shim, not in local time, but the error traces to the following location. I'm not a JS guy, so not quite sure how to correct in

function processScript(e) {
    if (e.ep)
      return;
    if (null !== e.getAttribute("noshim"))
      return;
    if (!e.src && !e.innerHTML)
      return;
    e.ep = true;
    const t = ar > 0;
    const s = sr > 0;
    t && ar++;
    s && sr++;
    const a = topLevelLoad(e.src || `${r}?${Ne++}`, getFetchOpts(e), !e.src && e.innerHTML, !c, t && tr).catch((e => {
      setTimeout((() => {
        throw e
      }));
      pe(e)
    }));
    t && (tr = a.then(readyStateCompleteCheck));
    s && a.then(domContentLoadedCheck)
  }
@Merovex Merovex changed the title Does not appear to work in Rails 7 Does not appear to work in Rails 7 using import-map (new Rails default) Oct 28, 2021
@Merovex
Copy link
Author

Merovex commented Oct 28, 2021

This works as import:

import * as LocalTime from "helpers/local-time"
LocalTime.start()

But now I'm to the next error:

TypeError: undefined is not an object (evaluating 'this')

@phillipspc
Copy link

I was getting a similar error

SyntaxError: Importing binding name 'default' cannot be resolved by star export entries.

after using ./bin/importmap pin local-time --download. If I exclude the --download flag, and just use the CDN version, this error goes away. 🤷‍♂️

@1klap
Copy link

1klap commented Feb 3, 2022

I have the same issue...using importmaps with the downloaded file causes problem while using the CDN works perfectly.
I don"t understand why that is the case, why does it make a difference from where the file is loaded...

@1klap
Copy link

1klap commented Feb 3, 2022

Ok, the problem seems to come from the js module that is bundled with this gem. The asset pipeline serves that one instead of the one in vendor/javascript and it seems to have problems with the ESM loading.

My workaround to still use importmaps and downloaded js modules was to rename the file to avoid this conflict.

  • $ bin/importmaps pin local-time --download
  • rename vendor/javascript/local-time.js to vendor/javascript/local-time-cdn.js
  • change pin in importmap.rb to pin "local-time-cdn"
  • load LocalTime from that module instead
import LocalTime from "local-time-cdn"
LocalTime.start()

Tested in Firefox 96 and Chrome 97

Edit:
To illustrate the issue, here is the js module from this gem:
https://raw.githubusercontent.com/basecamp/local_time/main/app/assets/javascripts/local-time.js
And the js module that is loaded via importmaps from jspm:
https://ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js

@Merovex
Copy link
Author

Merovex commented Jun 25, 2022

Back to this again. Rails 7 application, using the CDN. The following code did not work:

import * as LocalTime from "local-time"
LocalTime.start()

On a hunch, I tried the following, which worked perfectly:

import LocalTime from "local-time"
LocalTime.start()

This uses the CDN version. 🤷🏻‍♂️

RyanJWolfe added a commit to RyanJWolfe/blog that referenced this issue Jul 1, 2022
@josefarias
Copy link
Contributor

@1klap's reply hits the nail on the head. Thanks!

Note that there's a way to still reference the library in JS by its original name. Just add the to: option in config/importmap.rb:

pin "local-time", to: "vendored-local-time.js"

Then, you can:

import LocalTime from "local-time"
LocalTime.start()

Crucially, the vendored file needs to be renamed to something other than local-time.js.

This won't be a problem anymore once #134 is released.

@vietqhoang
Copy link

vietqhoang commented Sep 18, 2023

@josefarias Thanks for addressing the problem in your recent changes. Are there plans to do a version bump?

@josefarias
Copy link
Contributor

josefarias commented Sep 18, 2023

Hey @vietqhoang, I plan to spend my upcoming cooldown tying up loose ends in this library — including cutting a new release. So no promises, but it might happen soon.

In the meantime, you can vendor the JS library (bundled versions are checked into the repo here), and you can point your Gemfile version to the main branch for the Ruby library.

EDIT: I should add the disclaimer that you should test that your app works correctly while running on main before shipping to production.

EDIT 2: This work didn't make the cut this last cooldown. Maybe next one. Sorry! Can't make any promises.

muxinqi added a commit to muxinqi/breakfast_tracker that referenced this issue Oct 15, 2023
@mjankowski
Copy link

With downloading the new default in importmap-rails - rails/importmap-rails#217 - I suspect people using this lib are going to bump into this issue more. Thanks for the workaround guidance! Would love to see version bump with changes, but noted on priorities.

@marckohlbrugge
Copy link

Could someone share up-to-date and complete instructions on how make local_time work with the latest importmap-rails? I tried following @1klap's approach, but bin/importmap pin local-time --download returns Couldn't find any packages in ["local-time", "--download"] on jspm

@josefarias
Copy link
Contributor

josefarias commented Jan 13, 2024

@marckohlbrugge, are you using the latest importmap-rails? If so, then I don't think the --download option works anymore as it's not needed, per rails/importmap-rails#217.

This does it for me:
(EDIT: it's important to understand what the commands below are doing before running them so you can revert the necessary bits when we cut the new release — hopefully as soon as next week, but no promises)

❯ rails new test_app
❯ cd test_app
❯ git add .
❯ git commit -m "Initial commit"
❯ bin/importmap pin local-time
#=> Pinning "local-time" to vendor/javascript/local-time.js via download from https://ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js
❯ mv vendor/javascript/local-time.js vendor/javascript/vendored-local-time.js
❯ sed -i '' '$ s/pin "local-time" # @2.1.0/pin "local-time", to: "vendored-local-time.js" # @2.1.0/' ./config/importmap.rb
❯ git add .
❯ git diff --cached

Results in:

diff --git a/config/importmap.rb b/config/importmap.rb
index bc060ed..a3aa833 100644
--- a/config/importmap.rb
+++ b/config/importmap.rb
@@ -5,3 +5,4 @@ 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 "local-time", to: "vendored-local-time.js" # @2.1.0
diff --git a/vendor/javascript/vendored-local-time.js b/vendor/javascript/vendored-local-time.js
new file mode 100644
index 0000000..bd59480
--- /dev/null
+++ b/vendor/javascript/vendored-local-time.js
@@ -0,0 +1,2 @@
+var r="undefined"!==typeof globalThis?globalThis:"undefined"!==type [truncated...]

The readme should take you the rest of the way.

Note that renaming the vendored file and editing importmap.rb won't be necessary when we cut the new release.

@dwightwatson
Copy link

I've using the latest version of importmap-rails. Having the same issue without the --download argument.

➜  app git:(main) ✗ bin/importmap pin local-time
Couldn't find any packages in ["local-time"] on jspm

Tried on a fresh Rails app and have the same result.

➜  Sites cd blank 
➜  blank git:(main) ✗ bin/importmap pin local-time 
Couldn't find any packages in ["local-time"] on jspm

Relevant: rails/importmap-rails#231

@josefarias
Copy link
Contributor

Managed to replicate, no clue why it was working for me yesterday 🤷🏻‍♂️

Passing --from=jspm.io seems to work:

❯ bin/importmap pin local-time
#=> Couldn't find any packages in ["local-time"] on jspm
❯ bin/importmap pin local-time --from=jspm.io
#=> Pinning "local-time" to vendor/javascript/local-time.js via download from https://ga.jspm.io/npm:local-time@2.1.0/app/assets/javascripts/local-time.js

Looks like a breaking change in the jspm API. Made a PR to fix in importmap-rails: rails/importmap-rails#234

@josefarias
Copy link
Contributor

I've just released the newest version. This should now work without having to rename anything. So:

❯ rails new test_app
❯ cd test_app
❯ bundle add local_time
❯ bundle install
❯ bin/importmap pin local-time # works now per https://github.com/rails/importmap-rails/pull/234#issuecomment-1892668735
#=> Pinning "local-time" to vendor/javascript/local-time.js via download from https://ga.jspm.io/npm:local-time@3.0.2/app/assets/javascripts/local-time.es2017-esm.js

Then follow the readme to import and start the library. Let me know if you run into trouble, preferably creating a new issue if unrelated to this one.

@mjankowski
Copy link

Thanks for quick turnaround -- works as expected after version bump.

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

8 participants