Webpacker: Allow ERB in config/webpacker.yml

Created on 16 Oct 2017  ·  12Comments  ·  Source: rails/webpacker

Any chance we could get ERB support in the config/webpacker.yml file? I'd like to dynamically set resolved_paths.

Most helpful comment

The lack of ERB parsing is hugely shocking when used within a Rails app, where it is conventionally expected to be supported.

Our use-case is to set the dev server port via an environment variable. However, webpacker.yml being the lone yml file in a Rails app to not be parsed via ERB ought to be enough on its own to warrant a revisit.

If the config file is meant to be parsed by both the npm module as well as rails, then I would humbly suggest .json for the file format, which does not have the history and expectation of ERB support as yml does.

All 12 comments

Unfortunately no, since we use same yml file for npm package as well, which doesn't parse erb like Ruby.

I'd like to dynamically set resolved_paths.

Why you would like do this?

So I can support a large Rails engine we use. The engine is installed as a gem and thus I'd want to use the installed gem path in production and a relative path in development. My only option right now is to hard-code the gem's installed path, which includes the gem's version. It would be nice to dynamically determine that so I don't have to update this file every time my engine's version is updated.

edit: or maybe I can use a wildcard in the production path so I don't have to specify the version. I haven't tried that.

@robertgrimm I see, really wish we could use erb but unfortunately can't.

Yeah, the wildcard option might work 👍 give it go

Looks like wildcards in resolved_paths aren't supported right now. I was able to get it working by hacking getModulePaths in package/environment.js to run the resolved_paths elements through sync. This could be a useful thing to add to webpacker.

I have a much better solution now that doesn't require any modifications to the webpacker gem. In case future readers are interested, I wound up modifying resolve.modules in config/webpack/production.js. That way, I can use sync to get the path of my Rails engine.

@robertgrimm could you please provide an example of yours config/webpack/production.js ?

@shlima Sure

const environment = require('./environment')                                                                                                                                                                               
const { sync } = require('glob')                                                                                                                                                                                           

var env = environment.toWebpackConfig()                                                                                                                                                                                    

// Add the installed myengine gem path to resolve.modules.  This is done                                                                                                                                                   
// here, instead of in config/webpacker.yml, because we need to use 'sync'                                                                                                                                                 
// to get the installed path.  The alternative is to use config/webpacker.yml                                                                                                                                              
// and hard-code the ruby and myengine gem version in the path which                                                                                                                                                       
// isn't desirable.                                                                                                                                                                                                        
const myenginepath = '/usr/local/lib/ruby/gems/*/gems/myengine-*/app/javascript';                                                                                                                                          
env.resolve.modules = env.resolve.modules.concat(sync(myengine))                                                                                                                                                           

module.exports = env

I've replaced the name of my actual gem with myengine. Note that the production environment for this particular application is very controlled and always a FreeBSD image that we build, thus I can safely hardcode the path to where the production gems are installed; I can also safely assume there's only ever a single version of ruby and this gem installed at one time due to how we build our image. In any other situation, I wouldn't have done it like that. A more general, non platform specific solution (that would probably also work if you use rvm), would involve doing something like executing gem which myengine to find out where the gem is installed and using that instead.

The development and test environments are setup to use a relative path to where the engine lives in our source code repository instead of using the production version. I do this in config/webpacker.yml using something like resolved_paths: ["../myengine/app/javascript"] under both the development and test sections. My config/webpack/production.js file overrides that setting for production mode.

The lack of ERB parsing is hugely shocking when used within a Rails app, where it is conventionally expected to be supported.

Our use-case is to set the dev server port via an environment variable. However, webpacker.yml being the lone yml file in a Rails app to not be parsed via ERB ought to be enough on its own to warrant a revisit.

If the config file is meant to be parsed by both the npm module as well as rails, then I would humbly suggest .json for the file format, which does not have the history and expectation of ERB support as yml does.

@jasonkarns just found out there is a separate set of options for that – link. In your case:

WEBPACKER_DEV_SERVER_PORT=8080 ./bin/webpack-dev-server

@iurevych thanks!

I'm working on turning Mastodon into a Rails engine, and I have the same use-case as Robert, but I can't hardcode the path to the engine gem because the software needs the ability to be deployed anywhere. I was hoping to solve this with <%= Mastodon::Engine.root.join('app', 'javascript') %> in the resolved_paths.

I'll just hardcode it for now on my dev machine while I solve other problems, but I'll have to come back to this. Maybe I can use an initializer or override some webpacker code.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ytbryan picture ytbryan  ·  3Comments

christianrojas picture christianrojas  ·  3Comments

naps62 picture naps62  ·  3Comments

itay-grudev picture itay-grudev  ·  3Comments

FrankFang picture FrankFang  ·  3Comments