Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uppy throws with latest create-react-app (react-scripts 5), Uncaught TypeError: nanoid is not a function #3376

Closed
waveiron opened this issue Dec 16, 2021 · 23 comments
Labels
Bug React React components or other React integration issues

Comments

@waveiron
Copy link

waveiron commented Dec 16, 2021

To reproduce the error:
https://github.com/waveiron/uppy_example_1
It was created using create-react-app, only App.tsx and package.json dependencies are changed

You can follow the steps to reproduce the error:

npx create-react-app --template typescript my_app

package.json

// ...
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.1",
    "@testing-library/react": "^12.1.2",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.0.3",
    "@types/node": "^16.11.14",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "@uppy/core": "^2.1.4",
    "@uppy/react": "^2.1.2",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-scripts": "5.0.0",
    "typescript": "^4.5.4",
    "web-vitals": "^2.1.2"
  },
// ...

App.tsx

import Uppy from '@uppy/core';
import { Dashboard, useUppy } from '@uppy/react';
import React from 'react';
import './App.css';

function App() {
  const uppy = useUppy(() => {
    return new Uppy();
  });
  return (
    <Dashboard uppy={uppy}/>
  );
}

export default App;
npm start

image

@waveiron waveiron changed the title Uppy throws with latest create-react-app (react-script 5) Uppy throws with latest create-react-app (react-scripts 5) Dec 16, 2021
@waveiron waveiron changed the title Uppy throws with latest create-react-app (react-scripts 5) Uppy throws with latest create-react-app (react-scripts 5), Uncaught TypeError: nanoid is not a function Dec 16, 2021
@waveiron
Copy link
Author

It it so weird, code works fine in codesandbox, but not locally, but they're identical.

Github repo:
https://github.com/waveiron/uppy_example_1

Codesandbox:
https://codesandbox.io/s/trusting-murdock-5s4ec?file=/src/App.tsx

Local screenshot:

uppy-sd.mp4

@waveiron
Copy link
Author

I've been struggling with this issue for 2 days, someone please help 😭😭

@waveiron
Copy link
Author

waveiron commented Dec 16, 2021

I made a screenshot for the whole process from scratch:

uppy2.mp4

@aduh95
Copy link
Contributor

aduh95 commented Dec 18, 2021

I'm able to reproduce. I think it's an issue with create-react-app itself, that returns a string to the require('nanoid/non-secure') call... I looks like they don't support .cjs as a file extension for JavaScript, and returns a string instead of the actual module 🤔 Not sure what is happening there, it might be worth opening an issue on create-react-app repo.
A not very satisfactory workaround would be to keep using the previous create-react-app version (npx create-react-app@4.0.3 my-project seems to be working) or use a different build tool.

@aduh95 aduh95 added Confirmed bug React React components or other React integration issues and removed Triage labels Dec 18, 2021
@Murderlon
Copy link
Member

I'm also not sure what we can do about this. @aduh95 if you're out of ideas feel free to close this.

@zackbloom
Copy link
Contributor

Can you help point us to where the .cjs file is? Might it be possible to use a .js extension? It doesn't appear that nanoid uses that extension: https://github.com/ai/nanoid/blob/main/non-secure/index.js

Given that the function being used is only about ten lines of code, might it be possible to just vendor that function?

@zackbloom
Copy link
Contributor

zackbloom commented Dec 23, 2021

This is the most likely place where .cjs could be included, but it doesn't actually resolve the issue: https://github.com/facebook/create-react-app/blob/f0a837c1f07ebd963ddbba2c2937d04fc1b79d40/packages/react-scripts/config/paths.js#L34-L46

For what it's worth, replacing const { nanoid } = require('nanoid/non-secure') with const { nanoid } = require('nanoid') does fix the problem.

Edit: I have a fork with that change here if it's helpful to anyone.

zackbloom added a commit to SendHeirloom/uppy that referenced this issue Dec 23, 2021
… note this may break React Native compatibility.
@Murderlon
Copy link
Member

Can you help point us to where the .cjs file is? Might it be possible to use a .js extension? It doesn't appear that nanoid uses that extension: https://github.com/ai/nanoid/blob/main/non-secure/index.js

Looking at the source code won't tell you that, the package uses dual-publish, so it will output multiple builds, including cjs.

For what it's worth, replacing const { nanoid } = require('nanoid/non-secure') with const { nanoid } = require('nanoid') does fix the problem.

We recently switched to non-secure to avoid a React Native limitation. But in the case of React Native, it could also be fixed by adding a additional package, but we can't do that here.

@aduh95 should we revert?

@aduh95
Copy link
Contributor

aduh95 commented Dec 23, 2021

Can you help point us to where the .cjs file is? Might it be possible to use a .js extension?

https://unpkg.com/nanoid@3.1.30/non-secure/index.cjs

I don't think using .js extension would help.

should we revert?

I'm not sure, I think using the non-secure implementation is beneficial for us (we don't use nanoid for anything related to security) as it decreases the bundle size and works natively in more places. The issue here is with create-react-app specifically, I'm not sure it's worth making Uppy bigger in bundle size for everyone because of a bug in one build tool.
Has the bug been reported to create-react-app? If there's a fix incoming, it's definitely not worth reverting.

@zackbloom
Copy link
Contributor

zackbloom commented Dec 23, 2021

For anyone trying to understand the misconfiguration, it seems adding cjs to the list of extensions which should be processed by babel in areas like this solves it.

A short term solution is for anyone suffering this issue to eject their app from CRA, and make that change.

@aduh95
Copy link
Contributor

aduh95 commented Dec 28, 2021

Looking at the CRA GitHub repo, it looks like there are several open PRs trying to address .cjs support: https://github.com/facebook/create-react-app/pulls?q=is%3Apr+is%3Aopen+cjs
Given the bug is not on Uppy side, I think the correct thing to do is to close this as won't fix; until the bug is fixed upstream, you can use one of the workarounds listed above (or share yours if you find something else).

@aduh95 aduh95 closed this as completed Dec 28, 2021
@digitalpraesidium
Copy link

Hallo, referring to @zackbloom solution about replacing const { nanoid } = require('nanoid/non-secure') with const { nanoid } = require('nanoid'), how can i apply this solutions in my node_modules in React project? i am experiencing this issue and it is a blocking issue for me. Thanks a lot

manuelkiessling added a commit to hygieia-saas/hygieia-webapp that referenced this issue Feb 24, 2022
@duanecilliers
Copy link

Thanks @zackbloom. In response to #3376 (comment)
I used customize-cra to add a new webpack rule without ejecting.

I added the following in config-overrides.js

const { override, addWebpackModuleRule } = require('customize-cra')

module.exports = override(
  addWebpackModuleRule({
    test: /\.(cjs)$/,
    exclude: /@babel(?:\/|\\{1,2})runtime/,
    loader: require.resolve('babel-loader'),
    options: {
      babelrc: false,
      configFile: false,
      compact: false,
      presets: [
        [
          require.resolve('babel-preset-react-app/dependencies'),
          { helpers: true },
        ],
      ],
      cacheDirectory: true,
      // See #6846 for context on why cacheCompression is disabled
      cacheCompression: false,
      // Babel sourcemaps are needed for debugging into node_modules
      // code.  Without the options below, debuggers like VSCode
      // show incorrect code and set breakpoints on the wrong lines.
      sourceMaps: true,
      inputSourceMap: true,
    },
  })
)

@kamalesh777
Copy link

I have tried all suggested ways but it doesn't return any errorless result. It returns same error that is nanoid is not a function

@mbvenu
Copy link

mbvenu commented Mar 15, 2022

Do we have any progress on this issue

swouf added a commit to graasp/graasp-app-sticky-notes that referenced this issue Mar 21, 2022
@001123
Copy link

001123 commented Apr 6, 2022

Still error on react-scripts 5.0.0

@Murderlon
Copy link
Member

I still stand by @aduh95's point: #3376 (comment).

It's a problem on the CRA side, not us. Fortunately we are moving to ESM in the nearby future which could solve this.

@DavidDuwaer
Copy link

DavidDuwaer commented Apr 13, 2022

Also need a fix on this issue. It's breaking, so I guess the only option is to not use <Dashboard/>. Ejecting CRA is never an option; switching to something other than CRA is a similar way too large thing to do for a single library and the customize-cra fix in the comment above doesn't work for me (on the dev server, is what I've tested. Anyone who did get that to work?).

@oxyno-zeta
Copy link

oxyno-zeta commented Apr 14, 2022

@DavidDuwaer I used this customization on my project and this is working well. You can find it here: https://github.com/oxyno-zeta/s3-proxy-interfaces in the dashboard folder for example.
The configuration provided needs to have 'react-app-rewired' installed and configured in the package.json (replacing the cra commands).

Hope it will work for you too !

PS: for the story I reverted my eject for that customization ;) Thanks @duanecilliers

@DavidDuwaer
Copy link

DavidDuwaer commented Apr 14, 2022

Thanks a lot, it works now on my dev server. I simply forgot to replace react-scripts with react-app-rewired in package.json's script commands.

@johan-apo
Copy link

johan-apo commented May 1, 2022

I found a "solution", if you are using React 18 disable Strict mode. In NextJS change your next.config.js, change reactStrictMode from true to false. Don't forget resetting your development server (at least in NextJS which I am using).

@Ionut-Milas
Copy link

for those who encounter the same issue:
facebook/create-react-app#12021

@GuiltyRemnant
Copy link

For anyone trying to understand the misconfiguration, it seems adding cjs to the list of extensions which should be processed by babel in areas like this solves it.

A short term solution is for anyone suffering this issue to eject their app from CRA, and make that change.

Thank you, that solved it for me. Why do i have to change something in node_modules and why isnt that in the package by native?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug React React components or other React integration issues
Projects
None yet
Development

No branches or pull requests