Lukas Hanincik
Lukas Hanincik

Reputation: 41

React compiler end up with Unexpected token <

I am beginner in React and I am struggling with compiler error. Let me introduce my situation. I have two independent React applications:

  1. App A - Big ERP
  2. App B - "Plugin" to the App A

I supposed I will develop App B as an independent application. Then, I will install it to the App A (using npm install [email protected]/...) once I finish development of the App B. I expected I will call components from App B within the App A source code. Everything went fine until I run the compilation. I am receiving:

SyntaxError: /frontend/node_modules/connector_frontend/src/views/Connector/FormView/index.js: Unexpected token

In my /frontend/node_modules/connector_frontend/src/views/Connector/FormView/index.js there is following code:

const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
        <p>Hello world</p>
)
}
export default ConnectorFormView;

Error is ocuring at the position of <p>.

I call this functional component from App A (frontend/src/views/Connector/ConnectorNewEditView/index.js) like this

import ConnectorFormView from "connector_frontend/src/views/Connector/FormView";

const ConnectorNewEditView = () => {
return (<ConnectorFormView AppValues={appValues} secureFetch={secureFetch} />)
}
export default ConnectorNewEditView;

I tried to return just a plain text from the ConnectorFormView component like this:

const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
        'Hello world'
)
}
export default ConnectorFormView;

and it was compiled successfully, but once I return a JSX from the ConnectorFormView component the compiler get crashed.

Can anyone explain the source of this error please?

Upvotes: 2

Views: 384

Answers (1)

Lukas Hanincik
Lukas Hanincik

Reputation: 41

I successfully figured out the source of this problem and also I found a solution. I expected I can reuse however React component implemented in JSX. I expected, the only requirement is to install it, resp. download it in JSX form to my project using NPM. It's FALSE.

According to my research, I can reuse React components compiled from JSX to ES only. It is achievable using Babel. Another very important requiremen, it should not by installed as React application as I installed it. It must be installed as a NPM package with clearly defined set of exported components.

I found this paper https://levelup.gitconnected.com/publish-react-components-as-an-npm-package-7a671a2fb7f and I followed it step by step and finally I achieved desired result.

I can very briefly mention steps which I performed:

  1. Implemented my custom component (mentioned above)
const ConnectorFormView = ({ AppValues, secureFetch, ...rest }) => {
return (
        <p>Hello world</p>
)
}
export default ConnectorFormView;
  1. Added the component to /src/index.js file in order to export it for host App
import ConnectorFormView from './components/ConnectorFormView';

export { ConnectorFormView };
  1. Installed Babel and all needed presets
npm install --save-dev @babel/core @babel/cli @babel/preset-env 
npm install -save @babel/polyfill
  1. configured Babel - created file /babel.config.json with following content
{
 "presets": [
  [
   "@babel/env",
    {
     "targets": {
     "edge": "17",
     "firefox": "60",
     "chrome": "67",
     "safari": "11.1"
      },
   "useBuiltIns": "usage",
   "corejs": "3.6.5"
    }
],
   "@babel/preset-react"
]
}
  1. Added new script to the package.json to compile React components to ES:
"build": "rm -rf dist && NODE_ENV=production babel src --out-dir dist --copy-files";
  1. Executed npm run build to compile React components to ES. Compiled components are located in new dist folder.

  2. Adjusted package.json that looks like this now

{
  "name": "my_react_components",
  "version": "0.1.0",
  "private": true,
  "description": "Some description",
  "author": "Lukas",
  "main": "dist/index.js",
  "module": "dist/index.js",
  "files": [ "dist", "README.md" ],
  "dependencies": {
    .
    .
  },
  "scripts": {
    "build": "rm -rf dist && NODE_ENV=production babel src--out-dir dist --copy-files",
    .
    .
    .
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "devDependencies": {
    "@babel/cli": "^7.17.10",
    "@babel/core": "^7.18.5",
    "@babel/preset-env": "^7.18.2"
  }
}
  1. Pushed dist folder to the git.

  2. Installed repository to the host project using NPM

npm install https://github.com/my_custom/react_component.git
  1. Import and use the component from installed git repo
import ConnectorFormView from 'my_react_components';

function App() {
return (
   <ConnectorFormView />
);
}
export default App;

Actually that's all. I very recommend to see the attached paper at the beginning of this answer because I maybe skipped very important info for you.

Upvotes: 2

Related Questions