Receiving "TextEncoder is not a constructor" on an extremely basic IPFS node.js program, please help

Hi!

I have been really enjoying working with IPFS & OrbitDB writing straight browser javascript against https://cdn.jsdelivr.net/ libraries. I am quite comfortable in JS but have not worked in Node.JS or with NPM or Browserify at all. While I am tinkering on something that is exclusively client-side the deeper I get the more I am finding it harder and harder to get around all the Node “Require” references in examples and missing min.js files so I have decided to take a step back and work through Node.JS. I am having trouble at a very early step here that I have spent an inordinate amount of time road blocked on and would really value some guidance on. Here are the steps I am taking:

I setup my environment like this:

mkdir ipsm
cd ipsm
npm init
npm install http-server
npm install browserify

Create a basic html page at /public/index.html

<!DOCTYPE html>
<html>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

Create a JS that does nothing more than reference IPFS at /src/index.js .

const IPFS = require(‘ipfs’)

Modify package.json as follows:

{
  "name": "ipsm",
  "version": "0.0.1",
  "description": "TEST",
  "main": "index.js",
  "scripts": {
    "serve": "http-server -c-1 -p 12345 public",
    "bundle": "browserify src/index.js -o public/bundle.js -d",
    "start": "npm run bundle && npm run serve"
  },
  "author": "Michael Rosola",
  "license": "MIT",
  "dependencies": {
      "browserify": "^17.0.0",
      "http-server": "^0.12.3",
      "ipfs": "^0.53.0",
    }
}

Bundle and start the server:
npm start

Opening a browser I receive the following error:

utils.js:7 Uncaught TypeError: TextEncoder is not a constructor
at Object.446.ipfs-utils/src/temp-dir (utils.js:7)
at o (_prelude.js:1)
at _prelude.js:1
at Object.444…/utils (key.js:5)
at o (_prelude.js:1)
at _prelude.js:1
at Object.443…/adapter (index.js:3)
at o (_prelude.js:1)
at _prelude.js:1
at Object.632.cids (utils.js:6)

Below is utils.js with line 7 noted:

'use strict'

const tempdir = require('ipfs-utils/src/temp-dir')
const TextEncoder = require('ipfs-utils/src/text-encoder') <--- here
const TextDecoder = require('ipfs-utils/src/text-decoder')

exports.utf8Encoder = new TextEncoder('utf8')
exports.utf8Decoder = new TextDecoder('utf8')

What I am doing seems consistent with tutorials and examples I have seen. If I omit the reference to IFPS and instead console.log(“hello world”) in my index.js all is well. What am I doing wrong?

Appreciate your help,
Michael

TLDR: I gave up on Browserify, attempted with WebPack which I also couldn’t get to work and finally to Parcel which worked without too much fuss.

WebPack - I went down a rabbit hole of WebPack 5 not supporting node.js core libraries and attempting lots of wacky configs and installes to polyfill but ultimately I couldn’t get that to work either after it finally compiling but getting stuck on “process” not being defined as a browser error. I rolled back to an earlier version of WebPack and got to about the same place.

Parcel - It worked pretty much out of the box. The only problem I encountered was it failing to compile with an error of parcel cbor\lib\map.js: unknown Statement of type “ForOfStatement” which after a little searching online found I could resolve by adding the following to my package.json

  "browserslist": [
    "last 2 versions and not dead and > 2%"
  ]

Here is my full package.json for anyone that stumbles across this post in the future that might be helped by it:

{
  "name": "ipsm-parcel",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "serve": "http-server -c-1 -p 12345 dist",
    "build": "parcel build index.html",
    "start": "npm run build && npm run serve"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "http-server": "^0.12.3",
    "ipfs": "^0.53.0"
  },
  "devDependencies": {
    "parcel-bundler": "^1.12.4"
  },
  "browserslist": [
    "last 2 versions and not dead and > 2%"
  ]
}

Glad you settled on a toolchain that works for you. Browserify is good but outdated, as you found Webpack 5 recently dropped support for bundling node core module shims out of the box.

The examples folder in the js-ipfs project has sample projects that build with most popular build systems, you should be able to use those as starting points for your own project.

This absolutely is an issue with the current version of CRA. Created a demo repo: GitHub - elmariachi111/ipfs-textencoder-demo: demoes an issue with TS / CRA / IPFS 0.54. Broke my upgrades and I’m looking for solutions since ~4hs already. Imo that’s an urgent one.