最近、Rails 7 アプリケーションで Vite を使用して開発を進めている中で、特定のエラーに直面しました。そして、その解決策を共有したいと思います。
問題
開発中、以下のようなエラーがブラウザのコンソールに表示されました。
An import map is added after module script load was triggered.
localhost/:1 Uncaught TypeError: Failed to resolve module specifier "application". Relative references must start with either "/", "./", or "../".
このエラーは、JavaScript モジュールのインポートが適切に解決されないことに関連しています。
暫定的な解決策
エラーの原因を特定し解決する過程で、app/views/layouts/application.html.erb
ファイル内の以下の行をコメントアウトしたところ、エラーメッセージが消えました。
<%#= javascript_importmap_tags %>
この変更により、Vite が正しく機能し、エラーが解消されました。しかし、この方法は Importmap を使用している場合には適用できません。
Importmap を使用する場合の注意点
Vite と Importmap の併用については、今回のエラーを解決する明確な方法を見つけることができませんでした。Importmap を使用する場合、同様のエラーに直面する可能性があり、この記事の執筆時点ではまだ解決策を見つけていません。
まとめ
Rails 7 で Vite を使用して開発を行う場合、特定の設定が原因でエラーが発生することがあります。今回は、javascript_importmap_tags
のコメントアウトにより一時的な解決策を見つけましたが、Importmap を使用する場合の解決策については、さらなる調査が必要です。
開発中に同じエラーに直面した方がいれば、この情報が何らかの参考になれば幸いです。また、Importmap を使用する場合の解決策をご存じの方がいれば、情報の共有をお願いします。
補記
以下にコードを記載します。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>VueRails</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%#= javascript_importmap_tags %>
<%= vite_client_tag %>
<%#= vite_javascript_tag 'application' %>
<%= vite_javascript_tag 'entrypoints/application' %>
</head>
<body>
<%= yield %>
</body>
</html>
https://github.com/rails/importmap-rails
// viteつかうならこのファイルは不要な気がする
import "@hotwired/turbo-rails"
import "controllers/application"
console.log('Vite ⚡️ Rails')
console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify.app/guide/rails')
import 'vue2-animate/dist/vue2-animate.min.css';
import { createApp } from 'vue';
import ExampleComponent from '../components/ExampleComponent.vue';
const app = createApp(ExampleComponent);
app.mount('#app');
import { Application } from "@hotwired/stimulus"
const application = Application.start()
application.debug = false
window.Stimulus = application
export { application }
import { defineConfig } from 'vite';
import RubyPlugin from 'vite-plugin-ruby';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
RubyPlugin(),
vue(),
],
});