Actioncable broken by default in Rails 6 in prod

https://github.com/rails/rails/issues/35501

I filed this issue back when the Rails 6 betas were out. Due to a Webpacker 4 change where node_modules folder is transpiled by default, actioncable can sometimes conflict with other transpiled libraries and cause client-side JS errors in production.

This took me and another senior engineer about 12 hours to sort out (as we were one of the first apps to come across it) but I have to imagine with the gaining popularity of ActionCable (thanks to things like Stimulus Flex) other people are frustrated by this and burn a bunch of time looking for a solution.

I think the biggest frustration beyond something essential being potentially broken due to no fault of the user, is the lack of understanding if this will be fixed, or if we are all just expected to add the following to our environment.js going forward.

// Added due to issues with @rails/actioncable being transpiled by babel-loader
// https://github.com/rails/webpacker/blob/master/docs/v4-upgrade.md#excluding-node_modules-from-being-transpiled-by-babel-loader
// https://github.com/rails/rails/issues/35501#issuecomment-555312633
const nodeModulesLoader = environment.loaders.get('nodeModules')
if (!Array.isArray(nodeModulesLoader.exclude)) {
  nodeModulesLoader.exclude = (nodeModulesLoader.exclude == null)
    ? []
    : [nodeModulesLoader.exclude]
}
nodeModulesLoader.exclude.push(/\@rails\/actioncable/)

I am a huge fan of Rails and I’ve had really good experiences getting other critical bugs fixed and contributing directly to the project, but this one snuck by the team and I think it is pretty high impact.

8 Likes

Thanks for filing the issue in the first place and adding more context here!

1 Like

Started an investigation into this already! :pray:

6 Likes

I’d be curious to learn more details about the conflicts with other libraries.

I was able to finally get up to date with all of the new webpacker changes from April & May. I have created a PR to fix this here. Please tell me what you think.

See my comment here for detailed info, but here is the relevant info:

The inclusion of the nodeModules loader (which transpiles node_modules) is not a clear-cut topic; it can break things depending on what dependencies the user is using. For mapbox-gl, it has already been packed twice by the time it gets to node_modules. This problem usually arises when code is transpiled, then minified, then transpiled & minified again by webpacker.

This results in a kind of fidelity loss where included global polyfills, like _typeof, are overwritten by the global _typeof that webpacker provides. You can see this happening in Will’s pictures above.

1 Like