If you're using Webpacker, I recommend exporting your JavaScript application as a library.
First, export any references you'd like to access from your view. These references must be exported from the entrypoint to your Webpacker code, usually the application.js file, i.e. app/javascript/packs/application.js (Webpacker 5) or app/packs/entrypoints/application.js (Webpacker 6).
// app/javascript/packs/application.js
import { functionName } from '../src/functionName'
export functionName // <== we want this function to be available in the view
In your Webpacker config, you would add this snippet to indicate you want to treat your JavaScript code as a library.
Webpacker 5
// config/webpack/environment.js
const { environment } = require('@rails/webpacker')
environment.config.merge({
output: {
// Choose whatever you want for `library`, [name] is a placeholder
library: ['Packs', '[name]'],
// Attach the library to the global scope in the browser
libraryTarget: 'window'
},
})
module.exports
Webpacker 6
// config/webpack/base.js
const { webpackConfig, merge } = require('@rails/webpacker')
module.exports = merge(webpackConfig, {
output: {
// Makes exports from entry packs available to global scope, e.g.
library: ['Packs', '[name]'],
libraryTarget: 'window'
},
})
With the above configuration, webpack will export a module called Packs to the global scope. The Packs variable will have a property corresponding to each entry by [name]. For the entrypoint named application.js, then you would access your function as a property of Packs.application in your view.
Example:
<%= javascript_pack_tag 'application' %>
<script>
Packs.application.functionName()
</script>