BloomstY
BloomstY

Reputation: 61

const fetch = require("node-fetch"); ^ Error [ERR_REQUIRE_ESM]: require() of ES Module

I have a problem, I know nothing about programming and I want to make an nft collection, I am following this youtube video: https://www.youtube.com/watch?v=AaCgydeMu64

everything went fine until around (32:14) My text is identical to the one in the video so i dont understand what is going on. When i run the comand: node utils/nftport/uploadFile.js

it says:

const fetch = require("node-fetch");
              ^

Error [ERR_REQUIRE_ESM]: require() of ES Module ......\hashlips_art_engine-main\node_modules\node-fetch\src\index.js from ......\hashlips_art_engine-main\utils\nftport\uploadFile.js not supported.
Instead change the require of index.js in ......\hashlips_art_engine-main\utils\nftport\uploadFile.js to a dynamic import() which is available in all CommonJS modules.
    at Object.<anonymous> ......\hashlips_art_engine-main\utils\nftport\uploadFile.js:2:15) {
  code: ?[32m'ERR_REQUIRE_ESM'?[39m

NB!: (......) is just a writing replacement for the file that was supposed to be there

This is the code for uploadFile.js:

const FormData = require("form-data");
const fetch = require("node-fetch");
const basePath = process.cwd();
const fs = require("fs");

fs.readdirSync(`${basePath}/build/images`).forEach((file) => {
    const formData = new FormData();
    const fileStream = fs.createReadStream(`${basePath}/build/images/${file}`);
     formData.append("file", fileStream);

    let url = "▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉";

let options = {
  method: 'POST',
  headers: {
    Authorization: '▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉▉',
  },
  body: formData
};

fetch(url, options)
  .then(res => res.json())
  .then(json => {
      const fileName = path.parse(json.file_name).name;
      let rawdata = fs.readFileSync(`${basePath}/build/json/${fileName}.json`);
      let metaData = JSON.parse(rawdata);

      metaData.file_url = json.ipfs_url;

      fs.writeFileSync(`${basePath}/build/json/${fileName}.json`,JSON.stringify(metaData, null, 2));

      console.log(`${json.file_name} upload & ${fileName}.jsonupdated!`);
  })
  .catch(err => console.error('error:' + err));

I've been stuck here forever and I feel like I have tried everything, but I know nothing about programming so I find this really hard! I've tried different versions of Node (I think) I've read all around the internett for solutions but nothing works! Please help me and please explain it simple so that I understand. Thanks!

Upvotes: 6

Views: 12904

Answers (2)

kirogasa
kirogasa

Reputation: 949

A new node-fetch version 3.0.0-beta.10 came out in the summer of 2021 with some breaking changes. One of them is the switch to ESM only package.

The peculiarity of the ESM package is that you can't mess it up with

const fetch = require('node-fetch')

you have to use

import fetch from 'node-fetch'

instead.

But the developers suggested an alternative way with async import():

const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));

This method does not require "type": "module" and etc, and will not cause an error if there are other imported libraries with require() in the same file.

Upvotes: 2

jfriend00
jfriend00

Reputation: 708026

First off, nodejs supports two different module types - the original CommonJS module that uses require() to load other modules and the newer ECMAScript modules (ESM) that use import to load other modules.

Your video tutorial is using the older CommonJS module type, but the latest version of node-fetch only supports being loaded by an ESM module which is not what you have. Thus, you have an incompatibility that results in the error you see.

You have three options I'm aware of:

  1. You can install an older version of node-fetch that should be entirely compatible with your video tutorial and using require().

  2. You can switch your code to an ESM module. To do so, you will have to load all modules with the appropriate import syntax (which your tutorial will not show you). Because CommonJS is the default module type in nodejs, switching to an ESM module involves either changing your filename extension to .mjs or creating a package.json file and setting type: "module" as a characteristic of your project.

  3. Instead of trying to load node-fetch, you can install and load the module node-fetch-commonjs instead. It's a CommonJS wrapper around node-fetch that should provide you compatibility.

Upvotes: 9

Related Questions