Cannot use node-fetch in lambda function

So this is a bit embarrassing, since I deployed several Netlify sites, with functions that are way more complex than this. But I’m kinda stumped, so here I am:
The novelty here is that I’m trying to deploy a function only - no front-end page whatsoever.

I created a simple function that uses node-fetch to call an API. I used netlify-lambda to package and serve the function. I keep getting an error r is not a function on the line when I call fetch.

  1. My package.json includes "node-fetch": "^2.6.0".

  2. My netlify.toml looks like this:

[build]
  command = "npm run build"
  functions = ".netlify/functions/"

With the build script being "build": "netlify-lambda build functions".

  1. The output from the build operation includes the line [37] ../node_modules/node-fetch/lib/index.mjs 39.9 KiB {0} [built]

  2. The code (with unnecessary parts removed) would look like this:

const fetch = require('node-fetch');
const constants = require('./constants');

class X {
  async _callAPI(requestXML) {
    try {
      const uri = constants.apiUrl + requestXML;
      console.log(uri);
      console.log(fetch);
      const response = await fetch(uri);
      console.log('ok');
      if (!response.ok) {
        throw new Error(response.statusText);
      }
      const body = await response.text();
      return body;
    }
    catch(ex) {
      throw ex;
    }
  }
}

So I get to the line where the uri is printed - all OK. I then decided to print fetch, and to my surprise got:

Object [Module] {
  Headers: [Getter],
  Request: [Getter],
  Response: [Getter],
  FetchError: [Getter],
  default: [Function: H] {
    isRedirect: [Function (anonymous)],
    Promise: [Function: Promise]
  }
}

Clearly, it is not a function. But why?

I went over the “compiled” code of the function, and the node-fetch code is included, as well as my code.

What am I doing wrong? About the only thing I can think of is that this code resides in a sub folder next to the actual function code with the handler, but that still makes no sense.

PS: I tried searching around and found this: https://github.com/node-fetch/node-fetch/issues/450. Turns out it was a great help: I removed node-fetch and installed node-fetch@1.7.3 and now everything works!

But the question still remains why?. AFAIK I’m not using webpack (unless netlify-lambda does). And how can this be fixed going forward? I don’t want to use a 2-versions-back version of a module.

Hey @Niceguy955,
That seems to me like a reasonable log of what fetch is since it’s a module, not just one function :slight_smile: Did anything else print after that? I also just checked out what I think is your function and it seems to be returning a response body that’s not an error. Have you gotten this working in the meantime? If not, would you mind sending your Netlify URL so we can dig in further? Thanks!

I got it soived. It has to do with some webpack issues.

I got this solved by changing to const fetch = request('node-fetch').default;.

My function returns a body to the handler function, which stringifys it, and wraps it with the appropriate header/status code for proper return so no issue there.

On this subject though, is there any way you could point me to t template/set of files on how to build the most minimal project with a single function, that uses ES6? No matter what I tried (renaming file extensions to .mjs, adding "type": "module to package.json etc.) something got broken. I had to revert all my code back to requires, and that’s what broke node-fetch.

Perhaps just suggest to the team building netlify-cli to add generators: minimal web site, minimal function, minimal React site (can use create-react-app to generate a site, and then add the Netlify flair).

Thanks for trying to assist!

2 Likes