-
I've successfully ported our app to Vite (thanks so much for vite_ruby and all your help!), and I'm trying to clean up some crufty corners. Our app has a few places where we pass some variables from ERB/haml to JS functions "installed" (i.e., defined on diff --git a/examples/rails/app/frontend/entrypoints/application.ts b/examples/rails/app/frontend/entrypoints/application.ts
index 1b68e3d..1f12af2 100644
--- a/examples/rails/app/frontend/entrypoints/application.ts
+++ b/examples/rails/app/frontend/entrypoints/application.ts
@@ -19,4 +19,6 @@ import.meta.globEager('../channels/**/*_channel.js')
Turbolinks.start()
ActiveStorage.start()
+window.foo = (arg) => console.log('arg is', arg);
+
console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify.app/guide/rails')
diff --git a/examples/rails/app/views/layouts/application.html.erb b/examples/rails/app/views/layouts/application.html.erb
index a8d49a3..12a1b79 100644
--- a/examples/rails/app/views/layouts/application.html.erb
+++ b/examples/rails/app/views/layouts/application.html.erb
@@ -11,6 +11,9 @@
<%= vite_stylesheet_tag 'styles.scss' %>
<%= vite_typescript_tag 'application', 'data-turbo-track': 'reload', media: 'all' %>
+ <script type="text/javascript">
+ window.foo("<%= ENV.fetch('SOME_ENV_VAR', 'default') %>");
+ </script>
</head>
<body> This doesn't work in vite_ruby because loading the application code happens asynchronously, so the templated, inlined JS runs before the function is even available and fails with <script type="text/javascript">
let intervalId = setInterval(() => {
if (foo in window) {
window.foo("<%= ENV.fetch('SOME_ENV_VAR', 'default') %>");
clearInterval(intervalId);
}
}, 100);
</script> This works but is obviously pretty gross. Are there better approaches to handling this? Or suggestions for refactoring code like this to work better with Vite? @rollup/plugin-define is not a good fit here, because some of the variables coming from ERB are dynamic. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 5 replies
-
If it's dynamic at startup, you could try using If the rendered data changes on every request, then the best approach is to ensure the rendered script is also Pseudo code: <script type="module">
import { foo } from '<%= vite_asset_path 'application.ts' %>'
foo("<%= ENV.fetch('SOME_ENV_VAR', 'default') %>");
</script> Basically, you would leverage the wonderful ES Module system to ensure code is loaded in the correct order. Good bye ordering issues! Some caveats:
|
Beta Was this translation helpful? Give feedback.
If it's dynamic at startup, you could try using
vite-plugin-erb
. I don't recommend it though, it's slow as it requires calling Ruby from JS.If the rendered data changes on every request, then the best approach is to ensure the rendered script is also
type="module"
, get a reference to the main script that defines the callback usingvite_asset_path
, and inject an import script.Pseudo code:
Basically, you would leverage the wonderful ES Module system to ensure code is loaded in the correct order. Good bye ordering issues!
Som…