hotwired / turbo

The speed of a single-page web application without having to write any JavaScript
https://turbo.hotwired.dev
MIT License
6.69k stars 423 forks source link

Window.fetch has been overwritten by Stimulus #1265

Closed jdpy19 closed 4 months ago

jdpy19 commented 4 months ago

Hey! I have spun up a new project this morning and I am running into an issue that is due to window.fetch being overwritten with the fetch in set operations from stimulus. Fetch

export function fetch<K, V>(map: Map<K, Set<V>>, key: K): Set<V> {
  let values = map.get(key)
  if (!values) {
    values = new Set()
    map.set(key, values)
  }
  return values
}

Hotwire is using window.fetch which should be the native https://github.com/hotwired/turbo/blob/89be8e4c206ea877183b7ac4a89f898363a14f0f/src/http/fetch.js#L6

Error

Screenshot 2024-05-24 at 12 27 12 PM

Package.json

{
  "name": "app",
  "private": true,
  "dependencies": {
    "@hotwired/stimulus": "^3.2.2",
    "@hotwired/turbo-rails": "^8.0.4",
    "esbuild": "^0.21.3",
    "sass": "^1.77.2"
  },
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --format=esm --outdir=app/assets/builds --public-path=/assets",
    "build:css": "sass ./app/assets/stylesheets/application.sass.scss:./app/assets/builds/application.css --no-source-map --load-path=node_modules"
  }
}

Gemfile

source "https://rubygems.org"

ruby "3.3.0"

gem "bcrypt", "~> 3.1.7"
gem "bootsnap", require: false
gem "cssbundling-rails"
gem "devise", "~> 4.9"
gem "image_processing", "~> 1.12"
gem "jbuilder"
gem "jsbundling-rails"
gem "pg", "~> 1.1"
gem "puma", ">= 5.0"
gem "rails", "~> 7.1.3"
gem "redis", ">= 4.0.1"
gem "simple_form", "~> 5.3"
gem "sprockets-rails"
gem "stimulus-rails"
gem "turbo-rails", '~> 1.0'

group :development, :test do
  gem "debug"
end

group :development do
  gem "htmlbeautifier"
  gem "web-console"
end

group :test do
  gem "capybara"
  gem "selenium-webdriver"
end
seanpdoyle commented 4 months ago

@jdpy19 thank you for opening this issue. Could you share your app/views/layouts/application.html.erb (mainly the line that imports application.js or however you're loading Turbo?

I can't find it now, but I recall an issue that was previously resolved when it was determined the Turbo was not being loaded within a <script type="module">, and that exports were polluting the global namespace.

jdpy19 commented 4 months ago

@seanpdoyle Thank you for the response.

Here is my app/views/layouts/application.html.erb

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>
    <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
    <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
  </head>
  <body>
    <%= render "layouts/navbar" %>
    <p class="notice"><%= notice %></p>
    <p class="alert"><%= alert %></p>
    <%= yield %>
  </body>
</html>
jdpy19 commented 4 months ago

Narrowing this down, when I remove the import of Application in app/javascript/controllers/application.js the issue resolves.. which I suppose is expected.

import { Application } from "@hotwired/stimulus";

const application = Application.start();

// Configure Stimulus development experience
application.debug = false;
window.Stimulus = application;

export { application };
seanpdoyle commented 4 months ago

@jdpy19 did you add jsbundling-rails to your Gemfile, then execute its installation script?

The javascript_include_tag should pass type: "module" (as it would be generated by rails javascript:install:[bun|esbuild|rollup|webpack]):

-<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
+<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true, type: "module" %>
jdpy19 commented 4 months ago

Ah, I pulled the application.html.erb from another rails app. Thank you for the help!