Disclaimer: I’m a member of the ember.js learning team. This isn’t a react vs ember article. They’re both awesome.
What if a team working with Ember wants to reuse an internal component built by a React team? Or maybe you know and appreciate multiple front end tool sets? This article for them and for you, oh open-minded developer!
This is based on my team’s experience when working with an enterprise client who has these changes in production for about six months now. The only factor to watch out for is the bundle size by ensuring that duplicates of React libraries aren’t included the app.
Let’s start off by making our Ember project aware of JSX syntax and give it the power to compile JSX code. Run the following command in your Ember project:
npm install --save-dev babel-plugin-transform-class-properties babel-plugin-transform-react-jsx
In your ember-cli-build.js file, make the following changes:
Next, we’ll need to enable eslint to identify JSX code. Run the following command in your ember project:
npm install --save-dev eslint-plugin-babel eslint-plugin-react babel-eslint;
Make the following changes to your .eslintrc.js file,
Add React & React DOM to our project by running,
npm install --save react react-dom
Then add the following changes to the ember-cli-build.js file:
Adding these imports will add React and ReactDOM global objects to our app. This is important because any React library we’ll import going forward will be expecting these globals to be available for their usage.
Let’s create vendor shims so that we can use es6 import syntax for these libraries. We’re doing this instead of using the amd transformation on the imports because the global objects aren’t created when you use the transformation.
Run the following commands & replace the contents of the generated files with the ones from the gist shown below. Then import them in the ember-cli-build.js file.
ember generate vendor-shim react ember generate vendor-shim react-dom
Let’s create a base class that we can use to create our React component wrappers. The idea behind this is to render one React component inside one Ember component. Doing so will help keep these components simple. Create a file app/react-component.js with the following content.
First let’s create the obligatory ‘hello world’ component by running ember g component hello-world with the content below,
That was easy 🙂. Notice how we’re passing the value “React” to the React component on line 8, this could be an Ember component property. Now moving on to a more complex sample.
Let’s add react-aria-modal to our app. Run npm install --save @sivakumar-kailasam/react-aria-modal and then make the following changes to the ember-cli-build.js file:
Now that we have it available to our app, let’s create the wrapper component.
ember g component aria-modal
This sample shows a way to bind methods between the React & Ember components. We’re updating the title that’s passed to the React component from within the Ember component’s methods & rerendering the react component on updates.
Notice in the recording below how the updates are immediately rerendered. That’s because these are incremental updates applied to the already rendered React component. Try the demo site linked at the end of this article to see for yourself.
All of this might’ve made it look easy for you to set out to do this on your own. But there’s an important factor I haven’t mentioned so far 😅.
I had to setup rollup.js on a fork of react-aria-modal for this demo app to work. You can refer to https://github.com/davidtheclark/react-aria-modal/compare/master...sivakumar-kailasam:master to find out what it might take to do so with rollup.
You can see the deployed app at https://sivakumar-kailasam.github.io/react-integration-sample/ & view the code shown in this blog at the repo below. Try viewing the app in both the Ember inspector & React dev tools for fun! 😎
If you like this article, follow me on twitter @sivakumar_k