Search code examples
reactjsnpmbabeljscreate-react-appunexpected-token

Babel/JSX Transpiler error on build when importing a module into new create-react-app project


React Noob here.

I have been stuck on this for a little while.

I have tried to add a module into a project I'm making, but found the same problem occurs when I run it with a new create-react-app.

I believe it is related to babel/JSX, because if I put the imported modules src into a fresh project or just into the src of the existing one it seems to compile fine, just not as an import.

1) set up new react app:

npx create-react-app test-project
cd test-project

2) install package:

npm install --save react-collision-provider

3) Add an import to the App.js

+ import { collisionProviderFactory } from 'react-collision-provider';

4) start project

npm start

Error:

./node_modules/react-collision-provider/src/components/collisionProviderFactory.js
SyntaxError: /Users/XXXXXXX/Documents/TestProjects/test-project/node_modules/react-collision-provider/src/components/collisionProviderFactory.js: Unexpected token (37:14)

  35 |     render() {
  36 |       const Component = this.props.component;
> 37 |       return (<Component
     |               ^
  38 |         onCollision={this.onCollision}
  39 |         updatePosition={this.updatePosition}
  40 |         {...this.props}

I have tried to mess around with different babel settings and ejecting the project but no luck. I heard CRA doesn't transpile node_modules only src, but not sure how to compile the JSX in advanced in the node_modules?

Thanks.


Solution

  • You're correct, the issue is that the react-collision-provider hasn't been properly transpiled to be understood by the browser. The browser doesn't naturally understand JSX as this is syntactic sugar to easily create your React component views. This is why we use babel to transform JSX into React.createElement(...); calls which is native JavaScript and can be understood by the browser.

    Perhaps you could do the following:

    1. Download babel-cli:

      npm install --save-dev @babel/cli

    2. Download @babel/plugin-transform-react-jsx plugin. We need this plugin since Babel 6 and up no longer have any native transforms for React. This is necessary to transpile unsupported JavaScript features, such as JSX, into native JavaScript which can be understood by the browser.

      npm install --save-dev @babel/plugin-transform-react-jsx

    3. Create a custom command within the scripts section of your package.json file to tranpile your react-collision-provider node module. Something like the following:

      "scripts": { ... "libTranspile": "babel --plugins @babel/transform-react-jsx <path_to_react_collison_module> --out-dir <path_to_react_collision_module> --copy-files", ... },

    4. Now you should be able to run your custom command to transpile your react-collision-provider module:

      npm run libTranspile

    The react-collision-provider module should now be transpiled, with all the JSX code sections replaced with React.createElement(...); calls.

    Hopefully that helps!