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

javascript質問 #40

Open
ojfubd opened this issue Aug 6, 2024 · 16 comments
Open

javascript質問 #40

ojfubd opened this issue Aug 6, 2024 · 16 comments

Comments

@ojfubd
Copy link
Owner

ojfubd commented Aug 6, 2024

◻︎実現したいこと

importmapでhotwiredフレームワークやstimulusやturbo-railsを使ってjavascriptをhtmlと併用してブラウザでjavascriptが動いていたが、esbuildに移行したことでjavascriptを動かしたい
ブランチ名:latestpopular

◻︎実現するために自分が選んだ手段とその理由
https://github.com/hotwired/stimulus-rails/tree/mainこの記事のWith JavaScript bundler
から下の手順を試してみた。
理由
githubのgemを見るのが一番正しいと思ったため

◻︎該当のソースコード

app/javascript/application.js

// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "./controllers"
import * as bootstrap from "bootstrap"

storyshare/app/javascript/controllers/index.js

import { application } from "./application"

import AController from "./a_controller"
application.register("a", AController)

import BodyController from "./body_controller"
application.register("body", BodyController)

import CharaAutoFillController from "./chara_auto_fill_controller"
application.register("chara-auto-fill", CharaAutoFillController)

import EraAutoFillController from "./era_auto_fill_controller"
application.register("era-auto-fill", EraAutoFillController)

import ExampleController from "./example_controller"
application.register("example", ExampleController)

import GenreAutoFillController from "./genre_auto_fill_controller"
application.register("genre-auto-fill", GenreAutoFillController)

import IssenController from "./issen_controller"
application.register("issen", IssenController)

import MemoCountController from "./memo_count_controller"
application.register("memo-count", MemoCountController)

import PlaceAutoFillController from "./place_auto_fill_controller"
application.register("place-auto-fill", PlaceAutoFillController)

import ThemeAutoFillController from "./theme_auto_fill_controller"
application.register("theme-auto-fill", ThemeAutoFillController)

memo_count_controller.js

import { Controller } from "@hotwired/stimulus"

// Connects to data-controller="auto-fill"
export default class extends Controller {
  connect() {
    const themeArea = document.getElementById('memo');
    if (themeArea) {
      themeArea.addEventListener('input', this.countChara3.bind(this));
    }
  }

  countChara3() {
    const textArea = document.getElementById('memo');
    const charCount = document.getElementById('charCount2');
    if (textArea && charCount) {
      charCount.textContent = textArea.value.length;
    }
  }

}

package.json

{
  "name": "app",
  "type": "module",
  "private": "true",
  "dependencies": {
    "@hotwired/stimulus": "^3.2.2",
    "@hotwired/turbo-rails": "^8.0.5",
    "@popperjs/core": "^2.11.8",
    "autoprefixer": "^10.4.19",
    "bootstrap": "^5.3.3",
    "bootstrap-icons": "^1.11.3",
    "esbuild": "0.19.0",
    "nodemon": "^3.1.0",
    "sass": "^1.77.2"
  },
  "scripts": {
    "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets"
  },
  "browserslist": [
    "defaults"
  ],
  "devDependencies": {}
}

◻︎その手段を使って実装するために参考にした公式ドキュメントや技術記事
https://github.com/hotwired/stimulus-rails/tree/main
evanw/esbuild#1765
◻︎環境の違い
自分のアプリ
"@hotwired/stimulus": "^3.2.2"

参考にしたgemのバージョン
stimulue-rails v1.3.3

◻︎自分のアプリの環境
"@hotwired/stimulus": "^3.2.2"
"@hotwired/turbo-rails": "^8.0.5"

◻︎エラーが出ているのかエラーが出ていないのか、エラーが出ているのであればどんなエラーが出ているのか

ブラウザのコンソール
Uncaught TypeError: Failed to resolve module specifier "@hotwired/turbo-rails". Relative references must start with either "/", "./", or "../".

Uncaught TypeError: モジュール指定子 "@hotwired/turbo-rails" の解決に失敗しました。相対参照は"/"、"./"、"../"のいずれかで始まる必要があります。

◻︎そのエラーの内容から推測したエラーの原因
相対パスが間違っているのではないかと推測した

package.jsonに"type": "module"を追加した

◻︎エラーの原因を解決するために自分で調べた記事
evanw/esbuild#1765

◻︎調べた記事を元に自分で行った対処法とその結果
対処法
package.jsonに"type": "module"を追加した
結果
何も変化がなかった

◻︎対処を行った際にわかったことや推測できたこと
package.jsonに"type": "module"を追加しても何も起きなかったこと

@kenchasonakai
Copy link

ありがとうございます!

yarn installは実行できているか確認してますかね?

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 6, 2024

コンテナの中でyarn installが行えているか(コンテナ内のnode_modulesに必要なディレクトリがあるか)も確認するとよいかなと思います

実行しました。
手順は下の写真であっていますか?
Image

Image

@kenchasonakai
Copy link

config/importmap.rbが残っているようですが、整理は済んでますか?
importmapについてきちんと調べてまずは必要ないものは削除するとよいと思います
https://github.com/ojfubd/storyshare/blob/latestpopular/config/importmap.rb

また、ブランチ運用についてGitHub Flowを学ぶとよいと思います

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 7, 2024

importmapを調べてまとめました。

importmapとは、ベアモジュール仕様でモジュールの名前だけを使ってインポートできるようになり、バージョン管理されたファイルへのエイリアスを設定できます。

importmapはRailsのアセットパイプラインで設定を行う時、簡略化されたモジュールのインポートが可能になります。
 importmapは主にRailsを使っている開発者がモジュールの依存関係を管理したいときや、開発環境でシンプルにモジュールをインポートしたいときに使用されます。
特に、アプリケーションの初期設定時や新しいモジュールを追加するときに役立ちます。

importmapの基本設定をするには、config/importmap.rbで必要なモジュール名とそのURLを定義します。
application.jsで定義したモジュール名を使ってアプリで使うモジュールなどをインポートします。
最後に、application.html.erbファイルに
<%= javascript_importmap_tags %>を記述します。

では、なぜimportmapを使うのかというと、従来のモジュールバンドラ(例:Webpack)を使わずに、ブラウザが直接モジュールを解決できるからです。これにより、開発環境が軽くなり、設定が簡単になります。

具体的なimportmapファイルの設定は、
以下のインポート定義は、import mapがなければ機能しません。

import React from "react"
インポート定義を有効にするには、たとえば以下のように定義する必要があるでしょう。

import React from "https://ga.jspm.io/npm:react@17.0.2/index.js"
ここでimport mapが登場して、https://ga.jspm.io/npm:react@17.0.2/index.jsアドレスにピン留めするreact名を定義します。このような情報が提供されれば、ブラウザは簡略化されたimport React from "react"定義を受け取れるようになります。

これにより、Webpackやnpmなどのツールを使わずに、ブラウザが直接モジュールを解決してくれるから、開発がシンプルになります。

importmapを削除しました。
Githubflowは、講師の人から今回は個人で開発するためブランチ名は自分で付けていいと言われたため、ブランチ名は自分でつけています。

@kenchasonakai
Copy link

importmapを調べてまとめました。

ちゃんと調べてまとめていてよいと思いました 🙆‍♂

Githubflowは、講師の人から今回は個人で開発するためブランチ名は自分で付けていいと言われたため、ブランチ名は自分でつけています。

理解して行っているとのこと承知しました 🙆‍♂

@kenchasonakai
Copy link

importmapを削除しました。

承知しました 🙆‍♂

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 7, 2024

しかし、まだJavascriptは動きません。どういう方針でエラーを解決すればいいですか

@kenchasonakai
Copy link

まずエラーがどこのファイルのどこの行のどの記述で起きているのかを探って、その後なぜ起きているのかを考えて解決していく方針が良いと思います

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 7, 2024

Uncaught TypeError: Failed to resolve module specifier "@hotwired/turbo-rails". Relative references must start with either "/", "./", or "../". new:1

他のページでは
localhost:1
と書かれていたそのため
ブラウザが新しいスクリプトを読み込もうとした時に失敗していると指していると言われてた
具体的にどこでエラーが発生したかは、通常はHTMLファイルの<script>タグの中で指定されたパスが関係している
ソース:ロボらんてくん

ロボランてくんのことが正しかった場合、ブラウザのここの部分がエラーになっていると考えた

<script src="/assets/application-f3e871e7be89ccb0adccd09d1fb0f2c5f0583d0626142906e3b227e5641284be.js" type="module" data-turbo-track="reload" defer="defer"></script> 

が参照している
app/assets/builds/application.jsやapplication.js.map
が問題だと考えた

javascript/application.jsで試しに"@hotwired/turbo-rails"を消してみたがエラーは消えなかった

ということは @hotwired/stimulusはエラーになっていないため app/assets/builds/application.jsとかapplication.js.mapが問題だと考えた

javascript/application.js

import { Turbo } from '@hotwired/turbo-rails';

と変更してもエラーが改善されません。

他に考えられるとしたら何が考えられますか

@kenchasonakai
Copy link

〇〇だと考えたと書いてありますので、対象の行の絞り込みが推測になってしまっているのかなと思います

推測ではなく確実に絞り込みましょう

コードをそれっぽく書き換えるのではなく、対象コードを消してみたり周辺コードも含めてコメントアウトしたりデバッグしたりしてみて確信を持てるようにしてみるといいと思います

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 10, 2024

Uncaught TypeError: Failed to resolve module specifier "@hotwired/turbo-rails". Relative references must start with either "/", "./", or "../". new:1
下から上のUncaught TypeErrorをエラーと呼ぶ

以下のことを試しましたが、まだエラーが出ます。他に何をすればいいと思いますか
条件1
<%= javascript_include_tag "application", type: "module", "data-turbo-track": "reload", defer: true %>を消したらエラーが消えたためjavascript_include_tag
javascriptの所だけがエラーの原因だとわかった

条件2
<%= javascript_include_tag "application", type: "module", "data-turbo-track": "reload", defer: true %>の所でtype:"module"を消したらエラーが下のUncaught SyntaxError: Cannot use import statement outside a moduleというエラーに変わった

条件3
application/javasript/application.js
でimport { Turbo } from "@hotwired/turbo-rails";の部分を消してもエラーが消えなかったということはこのファイルのコードが間違っているのではない

条件4
jsbuilding-railsをインストールしてみたが、それでもエラーが出ている

条件5
ブラウザのキャッシュクリアをしたがそれでもエラーが出る

@kenchasonakai
Copy link

application/javasript/application.js
でimport { Turbo } from "@hotwired/turbo-rails";の部分を消してもエラーが消えなかったということはこのファイルのコードが間違っているのではない

この部分出ないのであればどのファイルに記述してある@hotwired/turbo-railsが原因なのか見つけないといけないのかなと思いますがいかがでしょうか?

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 11, 2024

@hotwired/turbo-railsが使われている所がapplication/javasript/application.js以外ありません。

@kenchasonakai
Copy link

@hotwired/turbo-railsが使われている所がapplication/javasript/application.js以外ありません。

なるほど記述されていないのに読み込もうとするエラーが出ちゃうのですね 🤔
不思議ですね...
該当の記述が存在が存在しないということであればこちらとしてはどうアドバイスしていいかわからないですね

解決しそうな方法としては

  1. エラーの原因になっていそうな箇所を探して解消する
  2. 現状使いたい構成(importmapなのかesbuildなのか)を決めてrails new時にオプションを渡してデフォルトの状態を作成する→現状動かしている箇所の記述を最小限移植してみて今動かしたいもの(stimulus等)が動く環境を作成して現状のアプリの構成と比較して余計な記述・ファイルがないかコードの書き方は問題ないかを確認していく

みたいな感じかなと思います

@ojfubd
Copy link
Owner Author

ojfubd commented Aug 15, 2024

エラーを修正しようとして
全てのjavascriptのファイルを消してみましたpackage.json yarn.lock含めて
application.jsのファイルも全て消しても
Uncaught TypeError: Failed to resolve module specifier "@hotwired/turbo-rails". Relative references must start with either "/", "./", or "../". new:1のエラーは消えませんでした
しかし
<%= javascript_include_tag "application", type: "module"%>のtype: "module"部分を消したらエラーが変わりました。
そこで以下のエラーが発見されました。
Uncaught SyntaxError: Cannot use import statement outside a module (at application-f3e871e7be89ccb0adccd09d1fb0f2c5f0583d0626142906e3b227e5641284be.js:2:1)
(エラーの訳:モジュール外で import 文を使用できない )
というファイルがimportされていないというエラーが出ました
それを探ってみると以前消したはずのファイルがサーバー上では生き残っている?です。

このファイルを消したりするにはどうしたらいいのですか

Image

application-f3e871e7be89ccb0adccd09d1fb0f2c5f0583d0626142906e3b227e5641284be.js:2:1
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
❌import "@hotwired/turbo-rails"
import "controllers"
import * as bootstrap from "bootstrap";

@kenchasonakai
Copy link

assets:precompileしたりすると静的アセット(public/assets)というものが生成されてJS・CSSを変更しても変更が反映されずに静的アセットの方を読みに行ってしまうので静的アセットを削除して改めてbin/devを実行する等で対応できるかなと思います

bin/rails assets:clobber

というコマンドで削除出来るので一度調べてみてください

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

No branches or pull requests

2 participants