Reusing component from another create-react-app app with Babel, react-app-rewired
This is my scenario, I have an React app 1 that already have some template components, and in a new React app, I would like to reuse them.
Trial 1 — Referencing App1 from App2
As App1 is outside App2 folder, the way to make App2 able to reference App1 by adding a softlink in App2’s package.json dependencies block like following:
Then in App2, one can import like:
import * from ref_name
*some people suggest using “yarn link” approach, but seems not working for me.
Problem 1 — JSX not supported (here comes babel)
The reason is very simple, when App2 try to compile, it see jsx from App1 source code, which is not handled by create-react-app.
My solution is:
- At App1, add devDependencies @babel/core, @babel/cli, babel-preset-react-app
- go to App1 (the code that’s being referenced), then run:
NODE_ENV=development BABEL_ENV=development node node_modules/@babel/cli/bin/babel.js -d dist --presets=babel-preset-react-app src
The 2 environment variable NODE_ENV and BABEL_ENV are required by babel, which could be either “development” or “production”
Then run the babel-cli entry point (babel.js in above path), with “-d” to define output path, and use preset “babel-reset-react-app”
The final argument is the “src” folder which is the input for babel transpile.
Problem 2 — Relative reference of images or css
In App1, there are some image and css file that’s being imported in “assets” folder within “src” folder like below.
The command is as follow (assume we are inside “dist” folder, which is sibling to “src” folder)
ln -s ../src/assets/ ./assets
Problem 3 — Invalid hook call (actually is multiple react in same app)
The problem is because App1 and App2 both have their own react, they might have different version.
My solution is to leverage webpack alias, but given create-react-app manage the webpack (and I do not want to eject from create-react-app), so I leveraged the “react-app-rewired” together with “customize-cra” packages, and adding the “config-overrides.js” as below:
This make all react reference to the App2’s react package.
Solution credits goes to:
How-To: Fix 'more than one copy of react in the same app'
Here's the thing. You're building a reusable React component in separate npm package, you're testing out that component…
This is…well, 50/50 on challenging/frustration, and through this experience, helped me to understand more on the babel, create-react-app and react compiling…
Hope this helps someone.