matthew-andrews / isomorphic-fetch

Isomorphic WHATWG Fetch API, for Node & Browserify
MIT License
6.95k stars 289 forks source link

Node.js - realFetch.call is not a function #194

Open kevzettler opened 3 years ago

kevzettler commented 3 years ago

Trying to use this in a node.js worker and seeing error realFetch.call is not a function

(node:41803) UnhandledPromiseRejectionWarning: TypeError: realFetch.call is not a function
    at ../node_modules/isomorphic-fetch/fetch-npm-node.js.module.exports (/Users/kevzettler/code/hypeworks/build/webpack:/node_modules/isomorphic-fetch/fetch-npm-node.js:8:1)
    at AssetStore.<anonymous> (/Users/kevzettler/code/hypeworks/build/webpack:/AssetStore.ts:47:30)
    at step (/Users/kevzettler/code/hypeworks/build/0.server.worker.js:36403:23)
    at Object.next (/Users/kevzettler/code/hypeworks/build/0.server.worker.js:36384:53)
    at /Users/kevzettler/code/hypeworks/build/0.server.worker.js:36378:71
    at new Promise (<anonymous>)
    at ./AssetStore.ts.__awaiter (/Users/kevzettler/code/hypeworks/build/0.server.worker.js:36374:12)
    at AssetStore../AssetStore.ts.AssetStore.fetchBinary (/Users/kevzettler/code/hypeworks/build/0.server.worker.js:36443:16)
    at executeAction (/Users/kevzettler/code/hypeworks/build/webpack:/node_modules/mobx/lib/mobx.module.js:928:1)
    at AssetStore.fetchBinary (/Users/kevzettler/code/hypeworks/build/webpack:/node_modules/mobx/lib/mobx.module.js:915:1)
jgcmarins commented 3 years ago

facing the same problem

jgcmarins commented 3 years ago

tested on version 2.2.1 and version 3.0.0 and I can confirm it is not happening on version 2.2.1, only on version 3.0.0

hsiaosiyuan0 commented 3 years ago

I think it's a bug from node-fetch because it tagged itself as module see here so webpack load its .mjs instead of .js despite their exports have different semantics(scroll former two links to bottom to see the differences)

I guess you may in a isomorphic case, if so try to indicate webpack that node-fetch should be treated as it's commonjs module via webpack.config.js:

module.exports = {
  // ...
  externals: {
    'node-fetch': 'commonjs2 node-fetch',
  }
};
airhorns commented 3 years ago

I ended up switching to cross-fetch which seems to work in the same way without the same issue!

aseure commented 3 years ago

Same issue here. We've switched to cross-fetch as well which solves the issue for us.

FYI we've made it work with isomorphic-fetch with the following configuration but we thought it was too brittle to keep:

module.exports = {
  // ...
  resolve: {
    // ...
    mainFields: ['main', 'module']
  } 
}

With our target setting set to node the default for mainFields was ['module', 'main'].

We've also tried to made it per-dependency for both node-fetch and/or isomorphic-fetch by doing the following but this one did not work:

module.exports = {
  // ...
  resolve: {
    // ...
    byDependency: {
      'node-fetch': {
        mainFields: ['main', 'module']
      },
      'isomorphic-fetch': {
        mainFields: ['main', 'module']
      }
    }
  } 
}
jimmywarting commented 2 years ago

Now that NodeJS have built in fetch in v18+ then i think you should be using it instead.

now more dependency is needed any more.

sibelius commented 2 years ago

got it working using webpack alias

alias: {
      'node-fetch': path.join(
        cwd,
        '../../node_modules/node-fetch/lib/index.js',
      ),
    },
mletterle commented 1 year ago

I think it's a bug from node-fetch because it tagged itself as module see here so webpack load its .mjs instead of .js despite their exports have different semantics(scroll former two links to bottom to see the differences)

I guess you may in a isomorphic case, if so try to indicate webpack that node-fetch should be treated as it's commonjs module via webpack.config.js:

module.exports = {
  // ...
  externals: {
    'node-fetch': 'commonjs2 node-fetch',
  }
};

Just FYI for anyone else running into this, commonjs2 was a Webpack 4 externals type, if you're using Webpack 5 you'll want to specify node-commonjs. I.e.:

module.exports = {
  // ...
  externals: {
    'node-fetch': 'node-commonjs node-fetch',
  } 
};