Search code examples
reactjsnpmcompiler-errorsjsxunexpected-token

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?


Solution

  • 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.