react-rails icon indicating copy to clipboard operation
react-rails copied to clipboard

Suggestion to add documentation on migrating from the Asset Pipeline to Webpacker.

Open theotherdon opened this issue 5 years ago • 3 comments

I'm working on a very big legacy Rails app where we recently started migrating React components from the Asset Pipeline to Webpacker. We started doing this because sourcemaps weren't working correctly and we figured out it had something to do with the Asset Pipeline. As we started on this, we really wanted a way to migrate components selectively so that we didn't have to do everything in one fell swoop and run the risk of introducing a lot of bugs in the process (the automated testing is a work in progress). After reading this issue and a little bit of tinkering, I was able to get things setup so that we're able to migrate components over selectively rather than in one fell swoop. The approach that I used was to allow the Asset Pipeline to continue loading React, but to switch over to the UJS loader for Webpacker. This allows you to avoid including React twice. I tried to do it vice-versa using Webpack's Provide Plugin, but I wasn't able to get this to work. Could just be because of some old dependencies in the app. At any rate, I'd be happy to highlight both approaches so that people can try both and use what works for them.

I think it would be great to add this information to the docs so that other people are aware of this option as I believe more people will be migrating to Webpacker in the near future. Would it be alright for me to open a PR with updates to the README on how to do this?

theotherdon avatar Jan 24 '20 22:01 theotherdon

Attempting the same thing myself -- I'd like to gradually migrate components over to webpacker. Do you have any details about how you did it written anywhere? @donald-s

mattboldt avatar Feb 20 '20 17:02 mattboldt

@donald-s Running into this again! hah. Curious if you have any updates.

mattboldt avatar Jul 28 '20 01:07 mattboldt

I figured this one out! And it was incredibly simple.

  1. Remove react_ujs from app/assets/javascripts/application.js, but keep react
  2. yarn add react_ujs react-dom
  3. Add the regular ReactRailsUJS code to app/javascript/packs/application.js
    var componentRequireContext = require.context('components', true)
    var ReactRailsUJS = require('react_ujs')
    ReactRailsUJS.useContext(componentRequireContext)
    
  4. Add react and any other libraries you need available globally to webpack's externals object:
    module.exports = {
      externals: {
        react: 'window.React',
        'react-dom': 'window.ReactDOM',
        PropTypes: 'window.PropTypes',
      }
    }
    

Now, any time you use <%= react_component 'FooBar' %>, it will look for a matching webpacked component first. If none are found, it will fall back to the global scope and try to mount an asset-pipeline component

I'll definitely be submitting a PR to add this to the docs, because this would have saved me a couple days!

mattboldt avatar Aug 05 '20 02:08 mattboldt

Closing the issue as per the above conversation.

alkesh26 avatar Nov 09 '22 10:11 alkesh26