77

I am currently trying to build a State Management Library for ReactJs. But as soon as I implement it into my React project (created with create-react-app), it starts dropping this error:

Failed to compile.

path/to/agile/dist/runtime.js 116:104
Module parse failed: Unexpected token (116:104)
File was processed with these loaders:
 * ./node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
|       if (subscriptionContainer instanceof sub_1.CallbackContainer) subscriptionContainer.callback(); // If Component based subscription call the updateMethod which every framework has to define
|
>       if (subscriptionContainer instanceof sub_1.ComponentContainer) if (this.agileInstance.integration?.updateMethod) this.agileInstance.integration?.updateMethod(subscriptionContainer.component, Runtime.formatChangedPropKeys(subscriptionContainer));
|     }); // Log Job
|

If I comment out the highlighted lines of code mentioned in the error, it jumps to another point and complains there. But it can't be a syntax error because then TypeScript would complain in the IDE, too.

How the tool works: At the start you have to define a framework, in this case React. Then you can create a State and subscribe this State to a React Functional Component via a Hook. The Hook used to bind the State to the React Component simply creates a callback which triggers a re-render (via mutating a useReducer) and assigns this callback to the subscribed State.

If you want to know more checkout this repo: https://github.com/agile-ts/agile

Dependencies:

Third Party State Management library:

  "dependencies": {
    "@types/chai": "^4.2.12",
    "@types/mocha": "^8.0.2",
    "chai": "^4.2.0",
    "eslint-config-prettier": "^6.11.0",
    "mocha": "^8.1.1",
    "prettier": "2.0.5",
    "ts-node": "^8.10.2",
    "tsc-watch": "^4.1.0",
    "tslib": "^2.0.0",
    "typescript": "^3.9.7"
  }
  • Node: v14.8.0

React Project:

"dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "@types/jest": "^24.0.0",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "3.4.3",
    "typescript": "~3.7.2",
    "agile-framework": "file:../../"
  },
  • React: 16.13.1
  • NPM: 6.14.7
Pavel Fedotov
  • 748
  • 1
  • 7
  • 29
BennoDev
  • 1,067
  • 1
  • 6
  • 17

6 Answers6

44

The problem is that you're emitting ES2020 to dist/. If you look at the line it's complaining about:

if (subscriptionContainer instanceof sub_1.ComponentContainer) if (this.agileInstance.integration?.updateMethod) this.agileInstance.integration?.updateMethod(subscriptionContainer.component, Runtime.formatChangedPropKeys(subscriptionContainer));
                                                                                              // ^^                                         // ^^

you can see it's using the optional chaining operator in the emitted code. Consumers of your library will therefore need to have appropriate configuration to handle this kind of code. Your example consumer, the CRA app, is using Babel; although the setup does have the transform for optional chaining, it's only run on the source code for the React app itself, not its dependencies (including your library).

One option for fixing it is to emit less modern code, which will reduce the amount of configuration needed by consumers. For example, if you target ES6 using the following settings in tsconfig.json:

{
    "target": "ES6",
    "lib": ["DOM", "ES6", "DOM.Iterable", "ScriptHost", "ES2016.Array.Include"],
    // ...
}

the React app can at least start without you needing to change your source code.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
  • @customcommander you probably need to eject to get to the tsconfig in CRA. Are you using the official TypeScript template? It should already be targeting older runtimes for browsers. – jonrsharpe Oct 31 '20 at 22:43
  • @customcommander that does seem to target es5, assuming you mean https://github.com/reduxjs/cra-template-redux-typescript/blob/master/tsconfig.json#L3, so it shouldn't be emitting optional chaining. – jonrsharpe Oct 31 '20 at 22:47
  • @customcommander I'm not sure how that's relevant to this, then; the configuration I show is for the OP's `tsconfig.json`, they're compiling their library from TypeScript to JavaScript for use in other people's apps, including the demo CRA one in their post. I've edited my answer to clarify this. – jonrsharpe Oct 31 '20 at 22:54
  • sounds perfect! @jonrsharpe could you please advice, if I consume some library that gives me troubles like this, how I can configure Angular 11 project to work around this issue (pdfjs-dist package)? – Dmitry Gusarov May 03 '21 at 22:25
36

In case you are not the author of the library, or you don't want to change it as the accepted answer suggests, you can do as follows:

  1. change browserslist as @adlerer suggests:

    "browserslist": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    

    (make sure you don't have special config for development in browserslist)

  2. clear npm cache:

    npm cache clean --force
    
  3. reinstall things like @Gel suggests:

    rm -rf node_modules && rm -f package-lock.json && npm i
    

This is what helped me after hours of research and trials.

Piotr Ma'niak
  • 698
  • 8
  • 17
8

Though it's late but still it may help someone. In my case, I forgot to add the

"jsx": "react"

in my tsconfig.json.

Aryan Shridhar
  • 176
  • 3
  • 7
4

In my case setting more conservative compilation targets in package.json helped to resolve this issue:

"browserslist": [
">0.2%",
"not dead",
"not op_mini all"],
adlerer
  • 1,010
  • 11
  • 14
2

The issue in this case is that the version 3.2.0 of react-leaflet doesn't work for every project (i don't really know why). im working with react using CRA take note before doing anything Now the solution...

  1. uninstall react-leaflet
  2. Go to package.json and paste this lines
"react-leaflet": ">=3.1.0 <3.2.0 || ^3.2.1",  
"@react-leaflet/core": ">=1.0.0 <1.1.0 || ^1.1.1",

that's the way i solved the problem. the link to the answer in another website. https://www.gitmemory.com/issue/PaulLeCam/react-leaflet/891/860223422

superdunck
  • 3,088
  • 1
  • 3
  • 22
0

In my case I was trying to import dependencies from "react-leaflet" to my old project but then just after importing dependencies I faced the same issue. I solved my problem by these procedures.

In terminal:

rm -rf node_modules && rm -f package-lock.json
npm cache clean --force

I know this may sound irrelevant but in next step I updated these five dependencies in "package.json" to latest versions:

1- "@testing-library/jest-dom"

2- "@testing-library/react"

3- "@testing-library/user-event"

4- "react-scripts"

5- "web-vitals"

I guess the problem is somehow related to two last dependencies but I updated all five of them just in case.

then in terminal:

npm i
sudo npm update -g
Benyamin
  • 77
  • 1
  • 9