2

I'd like to reuse a javascript function I wrote in several different views. How can I go about doing this in rails 6? The only solution I've been able to use so far is defining the function in a javascript file as window.functionName = function() {}

However many other posts about this say it's a bad solution and should be avoided. What's the proper way to define functions that I can use in my rails views?

1
  • What do you mean by "use in views"? Do you have javascript_tag in views? Commented Mar 13, 2021 at 17:38

1 Answer 1

5

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>
Sign up to request clarification or add additional context in comments.

1 Comment

thanks @rossta, excellent answer. this should be accepted as the correct answer

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.