Importing js-ipfs gives some webpack errors [Reactjs]

I can not import IPFS because some Webpack errors. I do not really know how to fix them but after searching some information I think that is something about Webpack 5.
I did the following steps:

npx create-react-app test-app
cd test-app
npm install ipfs

Then I imported IPFS inside App.js:

import Ipfs from 'ipfs';

And when I execute npm start I get the following errors:

Module build failed: UnhandledSchemeError: Reading from "node:fs" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Module build failed: UnhandledSchemeError: Reading from "node:https" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.


Module build failed: UnhandledSchemeError: Reading from "node:http" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.


Module build failed: UnhandledSchemeError: Reading from "node:path" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.


Module build failed: UnhandledSchemeError: Reading from "node:stream" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Module build failed: UnhandledSchemeError: Reading from "node:url" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Module build failed: UnhandledSchemeError: Reading from "node:util" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Module build failed: UnhandledSchemeError: Reading from "node:worker_threads" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Module build failed: UnhandledSchemeError: Reading from "node:zlib" is not handled by plugins (Unhandled scheme).
Webpack supports "data:" and "file:" URIs by default.
You may need an additional plugin to handle "node:" URIs.

Thatā€™s because js-ipfs is not a browser package, but a Node JS package.
All those imports are Node imports and Iā€™ve opened an issue on the utils repo for this (where it originates): `electron-fetch` dependency is not ESM compatible Ā· Issue #164 Ā· ipfs/js-ipfs-utils Ā· GitHub

I also notice you use ipfs instead of js-ipfs, which you should be using btw.

Iā€™m having a similar issue. is there a fix?

While I understand all support for js-ipfs has ceased in favour of the new ā€œHeliaā€ release, for reasons of backward compatibility, I would like to still use ipfs-core. However, Iā€™m running into the same issue as above with regards to IPFS as a module and packaging it with a webapp using Webpack. Therefore, I thought I would dump all of my findings there in the hope that someone has a solution.

As the OP said, when importing ipfs or ipfs-core, a bunch of errors are output and the build fails. Many of these errors are browser incompability issues; for example, there is no concept of a filesystem in the browserā€™s js engine so the ā€˜fsā€™ module is useless. Therefore, this error can be avoided by using webpackā€™s resolve.fallback to either polyfill or disable completely, e.g.

resolve: {
  fallback: {
    fs: false
  }
}

or, install the fs-browserify module and use it as a replacement for native node fs:

resolve: {
  fallback: {
    fs: 'fs/'
  }
}

However, this does not solve the problem of node: protocol imports. The node: import seems to be a relatively new and mostly pointless exercise in introducing added frustration and confusion to js developers. Anyway, putting that to one side, it seems this cumbersome feature is here to stay.

Now, while webpack is convinced the problem is resolved, none of their suggestions work. In particular, they suggest using externals to provide support for protocols (although any formal documentation about this is missing).

There is a way to work around this using something called an externalPreset, which solves the node: protocol issue (I think it is because webpack interprets the protocol as a url and imports them in a different order? To be honest, I donā€™t really understand this feature). Anyway, externalPreset solves the webpack build issue but results in a runtime error:

Uncaught (in promise) ReferenceError: require is not defined

so, it doesnā€™t really resolve anything.

So, to summarize:

  • This seems like an ongoing problem, that is, there is no way to include IPFS in a webpack build. Iā€™m also concerned that similar issues could arise even if I migrate to Helia,
  • This seems to be a Webpack v5 issue,
  • Someone else has suggested polyfills. As I noted, this solves other problems but not the node: protocol issue,
  • Webpack says they have fixed it but I have tried a number of permutations and cannot get Webpack to work,
  • There is a project called webpack-node-externals but it does not solve this problem,
  • The IPFS Examples webpack example does not compile and results in the same errors,
  • There is a prepackaged IPFS import which functions in the browser so IPFS must be getting it to build. However, it is not possible to determine which version of IPFS this build is from.

Therefore, based on my findings above, Iā€™m wondering if anyone has any suggestions or a better understanding of webpack, that, perhaps, they can provide some further insight. Because, at the moment, Iā€™m stuck with an app reliant at its core on IPFS but which I cannot package for the web using Webpack.

Iā€™m also happy to share my exact webpack.config.js if it helps.

Further investigation suggests that the ipfs examples for react app also donā€™t work with the latest version of js-ipfs (v0.18.1). In fact, the node: protocol issue seems to go back to 0.15 so installing ipfs-core 0.14.* has been the only solution so far. Iā€™m also guessing some of the other webpack-based examples donā€™t work (I thought Vue uses Vite but perhaps it is using webpack?)

Testing latest Helia (v1.3.12) doesnā€™t seem to suffer from the same problems as ifps-core. Iā€™m assuming better support for browsers with Helia.

The problem is coming from a library within ipfs-core, in particular @achingbrain/nat-port-mapper which is importing newer packages which feature the node: import protocol. If you install an older version of nat-port-mapper, the problem goes away:

npm i @achingbrain/nat-port-mapper@1.0.7