wallet-adapter: Create React App is broken by lack of default polyfills in Webpack 5

Edit by @jordansexton:

To anyone looking for a very good workaround right now, don’t use Create React App. Just use the react-ui-starter or material-ui-starter projects with Parcel, or the nextjs-starter project with Next.js, save yourself a huge hassle, and get much faster builds with SWC instead of Babel.


Describe the bug Broken build with CRA v5, unable to resolve modules.

To Reproduce Steps to reproduce the behavior:

  1. Initialize a new CRA project. npx create-react-app my-app-test
  2. Install and use any wallet-adapter packages
  3. See error
BREAKING CHANGE: The request './adapter' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

Solution Relative imports must include a file extension to follow ESM strict mode requirements introduced in Webpack 5. It’s valid typescript to include .js extensions as part of the import path 🤯 :

example.ts

import { Example } from './example.js';

compiles to

example.js

import { Example } from './example.js';

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 6
  • Comments: 63 (8 by maintainers)

Commits related to this issue

Most upvoted comments

Anyone have issue with latest wallet adapter with cra 4.0 ? I am trying clone https://github.com/exiled-apes/candy-machine-v2-mint then replace the wallet adapter with “@solana/wallet-adapter-wallets”: “^0.14.2” and hit error below when run npm start

./node_modules/@solana/wallet-adapter-wallets/lib/esm/adapters.mjs
Can't import the named export 'BitKeepWalletAdapter' from non EcmaScript module (only default export is available)

This is fixed via #299.

The core issue is that the Torus and Ledger JS libraries don’t correctly polyfill and incorrectly use globals, and this isn’t handled by Webpack 5 without additional configuration, which you can’t add with CRA5 alone. We use react-app-rewired to override, as Craco doesn’t support CRA5 yet.

See the new create-react-app-starter project. The key parts are the config-overrides.js file and npm:process dependency.

Published:

@TomLisankie thanks for understanding. #276 just needs to be tested before merging (I rushed to publish its predecessor #264 and broke all the packages) and I haven’t had time to test it yet.

Maybe we should #yolo merge this, publish it, and see?

@steveluscher lol

Published:

These packages now have strict ESM exports (.mjs files). This fixes Next.js 12-based projects which use Webpack 5 with strict ESM imports.

It doesn’t fix CRA 5-based projects because of a semi-related issue: Webpack 5 doesn’t include polyfills for Node.js APIs by default, so it breaks with buffer and crypto imports.

Even though this issue was about strict ESM imports, I’ll leave it open until CRA projects work.

https://www.npmjs.com/package/typescript-esm / https://github.com/kristoferbaxter/typescript-esm looks promising

When you add the tsc-esm compiler following the conclusion of TypeScript’s output, this compiler will remap all generated files to use ‘.mjs’ extensions for locally resolved items and rename every output’s extension to ‘.mjs’.

Sounds like what we want?

Nope, there’s no good workaround at this time, sorry. CRA 5 is not supported.

Did anyone manage to fix this issue?

./node_modules/@netless/window-manager/dist/index.mjs Can’t import the named export ‘AnimationMode’ from non EcmaScript module (only default export is available)

@jordansexton thanks for all of this. I took my CRA project and just copied over the releveant parts from the package.json (devDependencies) and config.json into my existing project and all is well

Published:

Using these dependencies should fix the polyfill / CRA problems with no additional config required.

Huge thanks to @steveluscher for his heroic effort debugging and fixing this both here and in upstream projects.

Any volunteers want to try out @steveluscher’s promising solution @ #264 (comment)

Would love to know if this works for more people!

I’d be more than happy to test this, but I’m a bit ignorant to how. After I create-react-app, how do I install Steven’s packages instead of “yarn add @solana/wallet-adapter-base … etc.” ?

#254 will fix this when merged.

I’ve seen that build error before, I don’t know that it’s related to this or unresolvable.

For the reasons we discussed before, I’m not comfortable with adding the extension to the source. It increases maintenance burden and eslint doesn’t work for it yet. I’m also not convinced yet that this is a reasonable convention to follow when I haven’t seen it used a single time in the wild.

I’ll pick this up and work on it today.

https://www.npmjs.com/package/typescript-esm / https://github.com/kristoferbaxter/typescript-esm looks promising

When you add the tsc-esm compiler following the conclusion of TypeScript’s output, this compiler will remap all generated files to use ‘.mjs’ extensions for locally resolved items and rename every output’s extension to ‘.mjs’.

Sounds like what we want?

This looks like it will do the job! I’ll play around with this today

@gpoole https://github.com/solana-labs/wallet-adapter/issues/246 is probably related to the Next.js issue. I’m also not familiar with it and haven’t tested with Next 12.

it seems like using mjs extensions for the esm exports has the broadest compatibility and resolves the issue, so is there a reason not to do that?

@cogoo you spent a good bit of time trying out different builds, wdyt?

Perhaps we should configure the starter projects to disable hoisting since they are supposed to run standalone. Comes at the expense of initial install time, but maybe worthwhile?

cc @cogoo

It’s relatively straightforward to take your code from your CRA 5 app and drop it into the CRA 4 based react-ui-starter project though.

It’s worth noting that yarn lint is also currently broken.

🧐 this is unrelated. Fixed this by adding the missing transient dependencies

yarn add eslint-config-react-app babel-eslint -W --dev

or by removing react-app/jest from material-ui-starter/package.json and react-ui-starter/package.json

 "eslintConfig": {
        "extends": [
             "react-app",
-            "react-app/jest"
        ]
    },