Search code examples
ruby-on-railswebpacker

Can't get variables on view that were set in JS files compiled by webpacker rails


Rails 5.2.3

Webpacker 4.0.2

I have layouts/application.html.erb where I call dateFormat.initialize();

this function is defined in javascript/packs/application.js

const dateFormat = {
  railsDateMask: "YYYY/MM/DD",

  initialize() {
  }
}

and when I go to the index page there is an exception in the browser console

ReferenceError: dateFormat is not defined

before - this code was in assets/javascripts/application.js and everything works fine

I have found a lot of explanations and one of the solutions was set it like not const dateFormat but like global.dateFormat, but I don't think that it's the best solution and maybe there is another way.


Solution

  • Webpack doesn't export anything to the global scope by default. You could do something like window.dateFormat = ... like you suggested, but I prefer to configure Webpack to export selected modules instead. It's a little more work but a lot more flexible and a lot less error-prone.

    First, you'll want to export your desired global references from your entry point(s). So, declare your object as an export from app/javascript/packs/application.js:

    export const dateFormat = { ... };
    

    Now tell Webpack you want to export your output to the window target from your Webpack config in config/webpack/environment.js.

    environment.config.merge({
      output: {
        library: ['Packs', '[name]'],
        libraryTarget: 'window',
      }
    })
    

    The above config says "make my application exports available on window from Packs.application". For example, to access your exported dateFormat object from the console or in your views, use window.Packs.application.dateFormat.

    Note: the namespace Packs.[name] is arbitrary; use whatever suits your application. The [name] placeholder will create a separate namespace-per-entrypoint, which, if you end up using multiple entrypoints, would be helpful to prevent collisions.