facebook / create-react-app

Set up a modern web app by running one command.
https://create-react-app.dev
MIT License
102.54k stars 26.79k forks source link

?? Operator results in "Unexpected Token" err when used in package #9468

Closed arogozine closed 3 years ago

arogozine commented 4 years ago

Describe the bug

If you import a package that uses ?? operator in code, create react app will fail when debugging.

This issue seems to appear only when debugging with such a library. (npm run start)

It builds (npm run build) without errors. So the toolchain for start vs build is in question here.

The operator works fine if used directly - not in the imported library code.

Did you try recovering your dependencies?

Issues occurred with multiple CRAs even with reinstalling node modules.

Which terms did you search for in User Guide?

Null Coalescing Operator Create React App There seems to be an issue about optional chaining.

Environment

Windows 10 10.0.17763 npm 6.14.5 node 14.4.0 Google Chrome was used to ensure async, let, const, classes, and ?? support.

Steps to reproduce

  1. Create a React App with TypeScript (Haven't tried without TS)
  2. Create NPM package (TS with target ESNext, module, commonjs, declaration) that uses the ?? operator
  3. Use package in your app.
  4. Run start script

Expected behavior

The application should compile and run successfully when started or when built..

Actual behavior

The application fails to compile due to the ?? in the library.

Failed to Compile, Unexpected token You may need an additional loader to handle the result of these loaders.

Reproducible demo

If needed I can brew something up. This was found in a work project.

bitjson commented 4 years ago

I'm encountering this issue too – here's a repo to reproduce: https://github.com/bitjson/bitauth-cra (npm install && npm start):

./node_modules/@bitauth/libauth/build/module/lib/template/compiler.js 112:37
Module parse failed: Unexpected token (112:37)
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.
|   }), {});
|   const entityOwnership = Object.entries(template.entities).reduce((all, [entityId, entity]) => ({ ...all,
>     ...Object.keys(entity.variables ?? {}).reduce((entityVariables, variableId) => ({ ...entityVariables,
|       [variableId]: entityId
|     }), {})

The nullish coalescing operator works as expected in App.js, the error only seems to occur when the operator appears in an external dependency. (Try replacing this block with console.log(undefined ?? "success!") to confirm.)

Does anyone have any tips for how to debug this issue?

bitjson commented 4 years ago

As another data point, the bitauth-ide repo is running react-scripts at version 3.4.1, and the same library (@bitauth/libauth) is being imported without any errors. I'm still trying to figure out where the difference is.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

bitjson commented 4 years ago

For any TypeScript library authors having trouble with this, one workaround is to switch your compilation target from esnext to es2019. That will at least downlevel all nullish coalescing operators (??) so they don't trigger this bug.

bkiac commented 4 years ago

Same error with react-scripts@3.4.3

bkiac commented 4 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

arogozine commented 3 years ago

EDIT: Does having last 1 version for production makes this fail to build? I need to only support modern browsers - and transpilation increases bundle size.

Looks like 4.0.0 was released - but hasn't been properly tested.

Anyone can confirm that 4.0.0 still doesn't work with ?? (with or without TS)?

ajayvikas commented 3 years ago

Still getting the error on 4.0.0

../dist/index.modern.js 88:119
Module parse failed: Unexpected token (88:119)
File was processed with these loaders:
 * ../node_modules/@pmmmwh/react-refresh-webpack-plugin/loader/index.js
 * ../node_modules/babel-loader/lib/index.js
You may need an additional loader to handle the result of these loaders.
| 
|   function numberMask(rawValue = emptyString, config) {
>     rawValue = clean(rawValue, options, (config === null || config === void 0 ? void 0 : config.currentCaretPosition) ?? -1);
|     let [integer, fraction] = rawValue.split(period);
|     const hasPeriod = rawValue.indexOf(period) > -1;
jxanders commented 3 years ago

I tried the browserslist workaround from @bkiac and it worked for me (I could build debug but not production, now I can do both.) I'm on node 12.18.4 and the build is working fine for me. Oddly enough, my coworker cannot build the project for debug or production.

We don't have react-scripts installed so it might be an issue unrelated to react-scripts

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had any recent activity. It will be closed in 5 days if no further activity occurs.

arogozine commented 3 years ago

I'm gonna bump it. But the fix may be to use CRACO or something to configure 4.0.1.

Sinled commented 3 years ago

any update here?

jtomaszewski commented 3 years ago

It happens to me on 4.0.1 , and I don't know any other workaround than forcing other libraries to not use esnext as the compilation target ( https://github.com/facebook/create-react-app/issues/9468#issuecomment-692963920 ). Which is far from nice.

megargayu commented 3 years ago

Is there any way to fix this with a javascript module? (The module I'm using gives the same error, but it was written in javascript). Do I have to edit the module myself?

manjur2904 commented 3 years ago

./node_modules/@react-leaflet/core/esm/path.js 10:41 Module parse failed: Unexpected token (10:41) File was processed with these loaders:

------- herte is my error guys. please help me..

flutterq commented 3 years ago

[Solved] Failed to compile : ./node_modules/@react-leaflet/core/esm/path.js 10:41 Module parse failed: Unexpected token (10:41)

Anil2144 commented 3 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

could you plz send your package.json file

Duoquote commented 3 years ago

Same issue here,

./node_modules/@react-leaflet/core/esm/path.js 10:41
Module parse failed: Unexpected token (10:41)
File was processed with these loaders:
 * ./node_modules/react-scripts/node_modules/babel-loader/lib/index.js  
You may need an additional loader to handle the result of these loaders.
|   useEffect(function updatePathOptions() {
|     if (props.pathOptions !== optionsRef.current) {
>       const options = props.pathOptions ?? {};
|       element.instance.setStyle(options);
|       optionsRef.current = options;
bertho-zero commented 3 years ago

Same error in a storybook

nicolo-danzi commented 3 years ago

As a temporary workaround you can specify "@react-leaflet/core": "1.0.2" as dependency and specify also "resolutions": { "react-leaflet/@react-leaflet/core": "1.0.2" } in package.json. This forces react-leaflet package to have @react-leaflet/core version 1.0.2 as dependency

Arvind-Muthukr commented 3 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

This works for react-leaflet also when you delete the .cache folder within node_modules and run yarn start again.

Hope this helps. This fixed it for me.

slutske22 commented 3 years ago

I have tried the fix to remove the "development" property from "browserlist", delete the .cache folder, and start again, I get this prompt from CRA:

? We're unable to detect target browsers.

Would you like to add the defaults to your package.json? › (Y/n)

If I choose yes, CRA writes the development property back in, and the run fails again. If I choose no, I get the message:

As of react-scripts >=2 you must specify targeted browsers.
Please add a browserslist key to your package.json.

Which makes no sense, because I'm not removing the browserslist key, just the development property of it. I even tried this:

"browserslist": {
  "production": [],
  "development": []
}

But the error persists. What can I do?

ShardanaSoft commented 3 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

This works for react-leaflet also when you delete the .cache folder within node_modules and run yarn start again.

Hope this helps. This fixed it for me.

doing this solved for me. thanks

akursat commented 3 years ago

As a temporary workaround you can specify "@react-leaflet/core": "1.0.2" as dependency and specify also "resolutions": { "react-leaflet/@react-leaflet/core": "1.0.2" } in package.json. This forces react-leaflet package to have @react-leaflet/core version 1.0.2 as dependency

This is not working for me.

iansu commented 3 years ago

This is an issue with third-party packages so there's not much we can do about it. Package authors should generally not be compiling for esnext. Consider opening an issue with those packages.

iphyman commented 3 years ago

Deleting the browserlist does not solve the problem for me as react-script automatically adds it back, this issue happens on installing some packages.

My workaround at the moment is to remove the package (NFT.Storage)😁 NFT Storage

iampava commented 3 years ago

Deleting .cache folder inside node_modules worked for me. Thanks ;)

stefnotch commented 3 years ago

This is an issue with third-party packages so there's not much we can do about it. Package authors should generally not be compiling for esnext. Consider opening an issue with those packages.

Now, I very much do understand that it's hard to constantly upgrade the React tooling to support all the latest features of Javascript. Especially when Javascript is moving so fast that other frameworks suffer from similar issues.

However, since the nullish coalescing (??) is supported in every major browser now, it would be quite lovely if React could also support it. After all, React feels like the most modern of the frameworks. Is there an issue that I can watch and thus get notified when it gets implemented? Or could this issue be reopened? https://caniuse.com/?search=nullish

mitschabaude commented 3 years ago

I agree with @stefnotch. This is not an issue with the 3rd-party package, since this package shipped syntax that is supported by the browser! It's the CRA build pipeline that tripped up on valid code.

I think any reasonable build pipeline in 2021 should understand ES2021 syntax! It should then either

As a package author, I don't want to start working around the quirks of downstream build pipelines.

SachiraDilthushka commented 3 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. you should delete the .cache folder within node_modules and run npm start again

lazycuh commented 3 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

This worked great for me, you have to remove node_modules and do npm install again for it to work.

turboborsuk commented 3 years ago

I had a similar problem with logical nullish assignment operator (??=) and changing browserslist / cache clearing solved it for me.

(commenting here in case someone searches to solve it too)

SohanR commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

After this, Do the following:

  1. Delete your node_modules folder
  2. Run npm cache clean --force
  3. Run npm install

Now everything should work as expected.

Inori-Lover commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

After this, Do the following:

  1. Delete your node_modules folder
  2. Run npm cache clean --force
  3. Run npm install

Now everything should work as expected.

thanks this comments! it remind me babel have cache,and i just delete the cache folder: node_modules\.cache

it work for me

JoCo356 commented 2 years ago

@nicolo-danzi what you said on 20th March worked for the problems that I had with react-leaflet/core. However I still have react-leaflet/esm related errors do you know any work around? Thanks in advance.

danylokarpenko commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

AND delete .cache from node_modules

WORKED for me! Thank you guys!

ghost commented 2 years ago

I have tried the fix to remove the "development" property from "browserlist", delete the .cache folder, and start again, I get this prompt from CRA:

? We're unable to detect target browsers.

Would you like to add the defaults to your package.json? › (Y/n)

If I choose yes, CRA writes the development property back in, and the run fails again. If I choose no, I get the message:

As of react-scripts >=2 you must specify targeted browsers.
Please add a browserslist key to your package.json.

Which makes no sense, because I'm not removing the browserslist key, just the development property of it. I even tried this:

"browserslist": {
  "production": [],
  "development": []
}

But the error persists. What can I do?

I am stuck with this too. I'm trying to import a react-leaflet map as a component to App.js. The process is not working for me. Please help.

nyinyinyanlin commented 2 years ago

I have tried the fix to remove the "development" property from "browserlist", delete the .cache folder, and start again, I get this prompt from CRA:

? We're unable to detect target browsers.

Would you like to add the defaults to your package.json? › (Y/n)

If I choose yes, CRA writes the development property back in, and the run fails again. If I choose no, I get the message:

As of react-scripts >=2 you must specify targeted browsers.
Please add a browserslist key to your package.json.

Which makes no sense, because I'm not removing the browserslist key, just the development property of it. I even tried this:

"browserslist": {
  "production": [],
  "development": []
}

But the error persists. What can I do?

I am stuck with this too. I'm trying to import a react-leaflet map as a component to App.js. The process is not working for me. Please help.

At least you can bypass development browser list requirement by setting "development": [ ] to "development": [ "defaults" ]. Worked for me.

jamime commented 2 years ago

The cause is exactly the same as https://github.com/facebook/create-react-app/pull/8526 which added support for nullish coalescing in the developers code (e.g. App.js) but not in node_modules.

Now that it is supported by all evergreen browsers it is reasonable to assume that there will be some NPM packages that do not transpile this.

I think the changes in #8526 should be added to https://github.com/facebook/create-react-app/blob/main/packages/babel-preset-react-app/dependencies.js until react-scripts is using a newer version of webpack that can handle this syntax.

I didn't want to change my browserslist because it would transpile other code unnecessarily, so I used CRACO.

npm install @babel/plugin-proposal-nullish-coalescing-operator --save-dev
// craco.config.js
module.exports = {
  babel: {
    plugins: [["@babel/plugin-proposal-nullish-coalescing-operator"]],
  },
};
Shivansh-yadav13 commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

This works for react-leaflet also when you delete the .cache folder within node_modules and run yarn start again.

Hope this helps. This fixed it for me.

Thankyou very much for the solution, worked for me!

fjerbi commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

Don't forget to delete the .cache folder in node_modules before you do the npm install

farukbigez commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

After this, Do the following:

  1. Delete your node_modules folder
  2. Run npm cache clean --force
  3. Run npm install

Now everything should work as expected.

that's solved the issue

smriti-spotnana commented 2 years ago

Do we know why did this fix the issue ? - note: it did fix the issue for me, but wanted to fully understand the reason behind

jamime commented 2 years ago

Apologies, wrong reply.

Do we know why did this fix the issue ? - note: it did fix the issue for me, but wanted to fully understand the reason behind

Because node_modules has a different babel preset.

babel-preset-react-app

https://github.com/facebook/create-react-app/blob/67b48688081d8ee3562b8ac1bf6ae6d44112745a/packages/react-scripts/config/webpack.config.js#L412-L424

vs babel-preset-react-app/dependencies

https://github.com/facebook/create-react-app/blob/67b48688081d8ee3562b8ac1bf6ae6d44112745a/packages/react-scripts/config/webpack.config.js#L464-L479

The craco config adds the plugin"@babel/plugin-proposal-nullish-coalescing-operator".

jrejaud commented 2 years ago

Changing browser targets from

 "browserslist": {
   "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
},

to

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

solved my issue. I think #8445, #8526 could be related. The issue is with aggressive browser targets like last 1 chrome version.

This resolved an issue I had with parsing PURE annotations with babel in a library I was using. Thank you!

./node_modules/react-square-web-payments-sdk/dist/components/divider/divider.es.js 12:15
Module parse failed: Unexpected token (12:15)
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.
|   return /*#__PURE__*/React.createElement(Line, { ...props
|   }, /*#__PURE__*/React.createElement(SpanText, { ...spanProps
>   }, children ?? "or"));
| };
|
acrabb commented 2 years ago

Hey all, I've been looking at this the past couple days, and its still breaking.

Unfortunately the browse list change didn't work for me. I installed '@babel/plugin-proposal-nullish-coalescing-operator and added it to the plugins array, and also no luck.

Any other solutions I missed that I should look at? Thanks

tkforce commented 1 year ago

Hey all, I've been looking at this the past couple days, and its still breaking.

Unfortunately the browse list change didn't work for me. I installed '@babel/plugin-proposal-nullish-coalescing-operator and added it to the plugins array, and also no luck.

Any other solutions I missed that I should look at? Thanks

@acrabb According to the doc: https://create-react-app.dev/docs/supported-browsers-features/#configuring-supported-browsers

When editing the browserslist config, you may notice that your changes don't get picked up right away. This is due to an issue in babel-loader not detecting the change in your package.json. A quick solution is to delete the node_modules/.cache folder and try again.

Deleting the node_modules/.cache works for me.

wftID3 commented 1 year ago

Deleting the node_modules/.cache worked for me. Thanks @tkforce

donkey-donkey commented 1 year ago

Hey all, I've been looking at this the past couple days, and its still breaking. Unfortunately the browse list change didn't work for me. I installed '@babel/plugin-proposal-nullish-coalescing-operator and added it to the plugins array, and also no luck. Any other solutions I missed that I should look at? Thanks

@acrabb According to the doc: https://create-react-app.dev/docs/supported-browsers-features/#configuring-supported-browsers

When editing the browserslist config, you may notice that your changes don't get picked up right away. This is due to an issue in babel-loader not detecting the change in your package.json. A quick solution is to delete the node_modules/.cache folder and try again.

Deleting the node_modules/.cache works for me.

this worked for me. thanks much.

shahsawar92 commented 1 year ago
{
  "name": "wits",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack-dev-server --open --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js",
    "analyz": "webpack --config webpack.analyzer.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.9.6",
    "@babel/plugin-transform-runtime": "^7.12.15",
    "@babel/polyfill": "^7.11.5",
    "@babel/preset-env": "^7.9.6",
    "@babel/preset-react": "^7.9.4",
    "@babel/runtime": "^7.12.13",
    "babel-loader": "^8.1.0",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^3.6.0",
    "file-loader": "^6.0.0",
    "html-loader": "^1.1.0",
    "html-webpack-plugin": "^4.3.0",
    "mini-css-extract-plugin": "^0.9.0",
    "node-sass": "^4.14.1",
    "optimize-css-assets-webpack-plugin": "^5.0.3",
    "sass-loader": "^8.0.2",
    "style-loader": "^1.2.1",
    "webpack": "^4.43.0",
    "webpack-bundle-analyzer": "^3.8.0",
    "webpack-cli": "^3.3.11",
    "webpack-dev-server": "^3.11.0",
    "webpack-merge": "^4.2.2"
  },
  "dependencies": {
    "@material-ui/core": "^4.11.0",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/lab": "^4.0.0-alpha.56",
    "@sweetalert/with-react": "^0.1.1",
    "axios": "^0.20.0",
    "canvas-gauges": "^2.1.7",
    "classnames": "^2.2.6",
    "downsample-lttb": "0.0.1",
    "expression-eval": "^5.0.0",
    "i18next": "^19.4.5",
    "i18next-browser-languagedetector": "^4.2.0",
    "leaflet": "^1.9.3",
    "moment": "^2.29.4",
    "plotly.js": "^2.18.2",
    "prop-types": "^15.7.2",
    "react": "^16.13.1",
    "react-alert": "^7.0.1",
    "react-alert-template-basic": "^1.0.0",
    "react-container-dimensions": "^1.4.1",
    "react-dom": "^16.13.1",
    "react-draggable": "^4.4.5",
    "react-grid-layout": "^1.3.4",
    "react-helmet-async": "^1.3.0",
    "react-i18next": "^11.5.0",
    "react-leaflet": "^4.2.1",
    "react-plotly.js": "^2.5.1",
    "react-query": "^3.39.1",
    "react-responsive-carousel": "^3.2.23",
    "react-router-dom": "^5.2.0",
    "use-interval": "^1.4.0",
    "use-window-focus": "^1.4.2"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not op_mini all"
  ]
}

and i am encountering the same error how can i resolve this?