Home
Support Forums

Getting "must use import to load ES module" when using `node-fetch` in Netlify Functions

My site is skyglass.netlify.app.

I have a function that works locally with netlify dev. It requires node-fetch like this:

const fetch = require('node-fetch');

When I deploy however, I get this error:

{"errorType":"Error","errorMessage":"Must use import to load ES Module: /var/task/node_modules/node-fetch/src/index.js\nrequire() of ES modules is not supported.\nrequire() of /var/task/node_modules/node-fetch/src/index.js from /var/task/functions/subscribe.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.\nInstead rename index.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/node_modules/node-fetch/package.json.\n","trace":["Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /var/task/node_modules/node-fetch/src/index.js","require() of ES modules is not supported.","require() of /var/task/node_modules/node-fetch/src/index.js from /var/task/functions/subscribe.js is an ES module file as it is a .js file whose nearest parent package.json contains \"type\": \"module\" which defines all .js files in that package scope as ES modules.","Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove \"type\": \"module\" from /var/task/node_modules/node-fetch/package.json.","","    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1015:13)","    at Module.load (internal/modules/cjs/loader.js:863:32)","    at Function.Module._load (internal/modules/cjs/loader.js:708:14)","    at Module.require (internal/modules/cjs/loader.js:887:19)","    at require (internal/modules/cjs/helpers.js:74:18)","    at Object.<anonymous> (/var/task/functions/subscribe.js:3:15)","    at Module._compile (internal/modules/cjs/loader.js:999:30)","    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)","    at Module.load (internal/modules/cjs/loader.js:863:32)","    at Function.Module._load (internal/modules/cjs/loader.js:708:14)"]}

I tried changing the import to import fetch from 'node-fetch';, but then I got this error both locally and deployed:

{"errorType":"Runtime.UserCodeSyntaxError","errorMessage":"SyntaxError: Cannot use import statement outside a module","trace":["Runtime.UserCodeSyntaxError: SyntaxError: Cannot use import statement outside a module","    at _loadUserApp (/var/runtime/UserFunction.js:98:13)","    at Object.module.exports.load (/var/runtime/UserFunction.js:140:17)","    at Object.<anonymous> (/var/runtime/index.js:43:30)","    at Module._compile (internal/modules/cjs/loader.js:999:30)","    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10)","    at Module.load (internal/modules/cjs/loader.js:863:32)","    at Function.Module._load (internal/modules/cjs/loader.js:708:14)","    at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12)","    at internal/main/run_main_module.js:17:47"]}

Hi @spacecrafter3d

I came across this a few days ago testing something locally. As per Loading and configuring the module

node-fetch from v3 is an ESM-only module - you are not able to import it with require() .

So you would now change

const fetch = require('node-fetch');

to

import fetch from 'node-fetch';

In doing so, you would need to change the node_bundler environment variable to esbuild e.g. in a netlify.toml file

[functions]
  node_bundler = "esbuild"

In order to use

const fetch = require('node-fetch');

you need to use node-fetch@2 (see npm docs) or load v3 asynchronously (from npm docs)

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

That did it, thanks!