Webpacker: Watch rails views and reload page on changes

Created on 9 Jan 2019  路  8Comments  路  Source: rails/webpacker

I'm currently using webpacker with page reloading on css/js changes and it all works just great. Thanks for this amazing piece of software. I was wondering - would that be possible to do the same for rails views? It would be great if updating erb or slim view could trigger a webpack page refresh (ideally without rebuilding entire js/css bundle).

I'm fully aware that's not the point of using webpack(er) and know there are solutions like guard and livereload for that but i would love to avoid using yet another deamon running in the background.

Thanks in advance for any clues!

Most helpful comment

Here's an example that won't cause webpack to do a full recompile. This will simply trigger a browser reload. Your specific watches may vary, but they're pretty easy to configure using an array of glob syntax w/ chokidar (which is already included by webpack) - just note that it doesn't accept regexes:

development.js:

const chokidar = require('chokidar')
environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.slim'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

All 8 comments

From what I can tell the stock (webpack) devServer only pays attention to files that are resolved by webpack.

I use the webpack BrowserSyncPlugin & files: ['./app/**/{*.erb,*.rb}'] to achieve this, but you might need to use http-proxy-middleware in order to re-proxy the existing webpackER devServer if you want to go that route. It is very dependant on your setup, best of luck!

Not quite as nice as using webpack itself, but I've got this working by using watchexec.

I run up webpack-dev-server, then run:

watchexec -w app/views touch app/javascript/packs/application.js

There's an even easier way, just set the devServer contentBase property like this in config/webpack/development.js

environment.config.devServer.watchContentBase = true
environment.config.devServer.contentBase = [
  path.join(__dirname, '../../app/views')
]

Here's an example that won't cause webpack to do a full recompile. This will simply trigger a browser reload. Your specific watches may vary, but they're pretty easy to configure using an array of glob syntax w/ chokidar (which is already included by webpack) - just note that it doesn't accept regexes:

development.js:

const chokidar = require('chokidar')
environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.slim'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

Here's an example that won't cause webpack to do a full recompile. This will simply trigger a browser reload. Your specific watches may vary, but they're pretty easy to configure using an array of glob syntax w/ chokidar (which is already included by webpack) - just note that it doesn't accept regexes:

development.js:

const chokidar = require('chokidar')
environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.slim'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

Hey, I can't seem to get this working. The "chokidar" isn't watching any changes in *.html.erb files

Here's an example that won't cause webpack to do a full recompile. This will simply trigger a browser reload. Your specific watches may vary, but they're pretty easy to configure using an array of glob syntax w/ chokidar (which is already included by webpack) - just note that it doesn't accept regexes:
development.js:

const chokidar = require('chokidar')
environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.erb'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

Hey, I can't seem to get this working. The "chokidar" isn't watching any changes in *.html.erb files

Yes, my glob was for slim templates, which are what I use. I've modified the code above to look for erb files (though anyone can & should modify these globs for their needs)

Here's an example that won't cause webpack to do a full recompile. This will simply trigger a browser reload. Your specific watches may vary, but they're pretty easy to configure using an array of glob syntax w/ chokidar (which is already included by webpack) - just note that it doesn't accept regexes:
development.js:

const chokidar = require('chokidar')
environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.erb'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

Hey, I can't seem to get this working. The "chokidar" isn't watching any changes in *.html.erb files

Yes, my glob was for slim templates, which are what I use. I've modified the code above to look for erb files (though anyone can & should modify these globs for their needs)

Thank you for that. I'm not sure what the issue was but after closing my terminal and restarting my server, it worked like a charm!

thanks, @swrobel that worked great!

Can confirm this works on Rails 6.0.3.1, webpacker 4.2.2 :+1:

My config/webpack/development.js:

process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')
const chokidar = require('chokidar')

environment.config.devServer.before = (app, server) => {
  chokidar.watch([
    'config/locales/*.yml',
    'app/views/**/*.erb'
  ]).on('change', () => server.sockWrite(server.sockets, 'content-changed'))
}

module.exports = environment.toWebpackConfig()
Was this page helpful?
0 / 5 - 0 ratings

Related issues

ijdickinson picture ijdickinson  路  3Comments

FrankFang picture FrankFang  路  3Comments

iChip picture iChip  路  3Comments

naps62 picture naps62  路  3Comments

eriknygren picture eriknygren  路  3Comments