简体   繁体   中英

How to make JS function global in webpacker Rails 6

I try to organise my frontend as I used to do in Rails 5. I had some js file with functions and used this functions in different places of code up to my needs. But in Rails 6 work with js is quite different. Anyway, I think I got the main idea about packs and webpacker. But how to use custom js functions? Write it in one file and use in another? There is should be the way to do it.

For example, I have some custom js pack:

app/javascript/packs/custom_pack_with_functions.coffee :

console.log 'hey'

@hi = () ->
  console.log 'HI'

And I expect that hi function will be available in my view.

some_view.html.slim :

= javascript_pack_tag 'custom_pack_with_functions'

javascript:
  hi()

But when I come to appropriate page, I see in console only following messages:

hey
ReferenceError: hi is not defined

How to define hi function to use it from anywhere?

Webpack does not make modules available to the global scope by default. Here are a few ways you can do it:

  1. Assign the function to the global window object, ie, window.hi = function() {... } . I don't like side effects like this in a lot of places so it's my least favorite option but perhaps the easiest to understand.

  2. You could look at using expose-loader . This would mean customizing your webpack config to "expose" selected functions from selected modules to the global scope. It could work well for a handful of cases but would get tedious for many use cases.

  3. Export selected functions from your entrypoint(s) and configure webpack to package your bundle as a library . This is my favorite approach if you prefer to call global functions from the view. I've written about this approach specifically for Webpacker on my blog .

     // app/javascript/packs/application.js export * from '../myGlobalFunctions' // config/webpack/environment.js environment.config.merge({ output: { // Makes exports from entry packs available to global scope, eg // Packs.application.myFunction library: ['Packs', '[name]'], libraryTarget: 'var' }, })
     :javascript Packs.application.hi()
  4. Don't use global functions at all; use a different mechanism to trigger the function from within your webpack JS, such from within an event listener for the given page or in the presence of a given element.

     // app/javascript/initializer.js import hi from '../hi'; document.addEventListener('DOMContentLoaded', () => { if ( /* some logic for my page is true */ ) { hi() } });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM