ipfs / js-ipfs

IPFS implementation in JavaScript
https://js.ipfs.tech
Other
7.44k stars 1.25k forks source link

Line const { globSource } = require(‘ipfs-http-client’); causes “fetch is not defined” #3508

Closed raphael10-collab closed 3 years ago

raphael10-collab commented 3 years ago

Severity:

Description:

Steps to reproduce the error:

In an electron app adding this line:

const { globSource } = require('ipfs-http-client');

causes this error message:

A JavaScript error occurred in the main process
Uncaught Exception:
ReferenceError: fetch is not defined
    at Object../node_modules/ipfs-utils/src/http/fetch.browser.js (/home/marco/webMatters
/electronMatters/IPFSbase/.webpack/main/index.js:42149:28)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:21:30)
    at Object../node_modules/ipfs-utils/src/http.js (/home/marco/webMatters/electronMatters
/IPFSbase/.webpack/main/index.js:41661:37)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:21:30)
    at Object../node_modules/ipfs-utils/src/files/url-source.js (/home/marco/webMatters
/electronMatters/IPFSbase/.webpack/main/index.js:41604:14)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:21:30)
    at Object../node_modules/ipfs-http-client/src/index.js (/home/marco/webMatters/electronMatters
/IPFSbase/.webpack/main/index.js:38633:19)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:21:30)
    at Object../src/add-to-ipfs.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:74544:24)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:21:30)

devDependencies: "ipfs-or-gateway": "^2.1.0", "electron": "^10.1.2",

dependencies: "ipfs": "^0.53.1", "ipfs-http-client": "^48.2.0", "ipfsd-ctl": "^7.2.0", "is-ipfs": "^2.0.0",

Other info:

node version: v14.5.0
O.S. : Ubuntu 18.04.4.Desktop

How to solve the problem?

achingbrain commented 3 years ago

Can you try updating to the latest version of electron?

raphael10-collab commented 3 years ago

Hi @achingbrain Alex!

I upgraded electron to the latest available version:

devDependencies:
    "electron": "^11.2.1",

but still get this error message when inserting the line const { globSource } = require('ipfs-http-client'); :

A JavaScript error occurred in the main process
Uncaught Exception:
 ReferenceError: fetch is not defined
    at Object../node_modules/ipfs-utils/src/http/fetch.browser.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
  /main/index.js:42149:28)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:21:30)
    at Object../node_modules/ipfs-utils/src/http.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:41661:37)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:21:30)
    at Object../node_modules/ipfs-utils/src/files/url-source.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:41604:14)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:21:30)
    at Object../node_modules/ipfs-http-client/src/index.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack
/main/index.js:38633:19)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:21:30)
    at Object../src/add-to-ipfs.js (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:74549:24)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IPFSbase/.webpack/main/index.js:21:30)
achingbrain commented 3 years ago

Are you running this in the main thread or the renderer?

raphael10-collab commented 3 years ago

@achingbrain

the require('ipfs-http-client') line is in a file called add-to-ipfs-js:

add-to-ipfs.js: const { globSource } = require('ipfs-http-client');

add-to-ipfs.js is imported in tray.js :

const { CONFIG_KEY: IPFS_PATH_KEY } = require('./ipfs-on-path')

and tray.js is imported in main.ts thread :

const setupTray = require('./tray');
raphael10-collab commented 3 years ago

@achingbrain to better see the error and discover the cause, you can download the repo, which is nothing more than part of code of ipfs-desktop I'm playing with: https://github.com/raphael10-collab/OnlyIPFS

After git cloning the repo, just do:

raphael10-collab commented 3 years ago

@achingbrain I realized that also only just importing ipfs in main.ts as done in js-ipfs examples: https://github.com/ipfs/js-ipfs/blob/master/examples/run-in-electron/main.js

const IPFS = require('ipfs');

produces this error:

fetch is not defined

This is a simple repo: https://github.com/raphael10-collab/OnlyIPFS

After git cloning the repo, just do:

yarn
yarn start
achingbrain commented 3 years ago

I think the problem is you're using the 'electron-renderer' webpack target to build for the main process, which then uses the browser overrides in package.json so you're getting browser code in a node process.

raphael10-collab commented 3 years ago

So... should I use

target: 'electron-main'

or

target: 'web'

?

I tested that moving all ipfs-related code to the renderer process and set target: 'web' it works fine, but I'm wondering if I've done the right thing, or should I keep the ipfs-related code to the main process and set target: 'electron-main'

raphael10-collab commented 3 years ago

@achingbrain

As suggested by a kind fellow in https://discuss.ipfs.io/ I tried to move the ipfs-related code to the main process main.ts .

With this webpack configuration:

/tools/webpack/webpack.main.js :

module.exports = {
  /**
   * This is the main entry point for your application, it's the first file
   * that runs in the main process.
   */
  entry: ['./src/main.ts'],
  // Put your normal webpack config below here
  module: {
    rules: require('./webpack.rules'),
  },
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'],
    alias: require('./webpack.aliases'),
  },
  // https://github.com/electron/electron/issues/9920
  //target: 'electron-renderer'
  target: 'electron-main'
};

/tools/webpack/webpack.renderer.js :

/ eslint-disable @typescript-eslint/no-var-requires / const rules = require('./webpack.rules'); const plugins = require('./webpack.plugins'); const aliases = require('./webpack.aliases');

module.exports = {
  // https://github.com/electron/electron/issues/9920
  target: 'electron-renderer',
  module: {
    rules,
  },
  plugins: plugins,
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'],
    alias: {
      // React Hot Loader Patch
      'react-dom': '@hot-loader/react-dom',
      // Custom Aliases
      ...aliases,
    },
  },
};

the import in main.ts works fine:

import Ipfs from 'ipfs';
import IpfsHttpClient from 'ipfs-http-client';

But when I add this line:

const { globSource } = IpfsHttpClient;

I get this error:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Module build failed (from ./node_modules/@marshallofsound/webpack-asset-relocator-loader/dist/index.js):
SyntaxError: Unexpected token (85:14)
    at Object.module.exports.pp$4.raise (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20834:13)
    at Object.module.exports.pp.unexpected (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18680:8)
    at Object.module.exports.pp$1.parseTryStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19069:49)
    at Object.module.exports.pp$1.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18834:32)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4539:118)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:42314:22)
    at Object.module.exports.pp$1.parseBlock (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19157:23)
    at Object.module.exports.pp$1.parseTryStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19073:24)
    at Object.module.exports.pp$1.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18834:32)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4539:118)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:42314:22)
    at Object.module.exports.pp$1.parseBlock (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19157:23)
    at Object.module.exports.pp$3.parseFunctionBody (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20675:22)
    at Object.module.exports.pp$3.parseArrowExpression (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20638:8)
    at Object.module.exports.pp$3.parseExprAtom (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20227:21)
    at Object.parseExprAtom (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4551:117)
    at Object../node_modules/fs-extra/lib/mkdirs/make-dir.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
 /main/index.js:13240:7)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/mkdirs/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:13217:44)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/copy-sync/copy-sync.js (/home/marco/webMatters/electronMatters/IpfsPlaying
/.webpack/main/index.js:12155:20)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/copy-sync/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:12332:13)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:13083:6)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)

With this code in main.ts :

import Ipfs from 'ipfs';
import IpfsHttpClient from 'ipfs-http-client';

export const ops = async () => {
  const node = await Ipfs.create({ repo: String(Math.random() + Date.now()) });
}

I get this error:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Module build failed (from ./node_modules/@marshallofsound/webpack-asset-relocator-loader/dist/index.js):
SyntaxError: Unexpected token (85:14)
    at Object.module.exports.pp$4.raise (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20834:13)
    at Object.module.exports.pp.unexpected (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18680:8)
    at Object.module.exports.pp$1.parseTryStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19069:49)
    at Object.module.exports.pp$1.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18834:32)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4539:118)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:42314:22)
    at Object.module.exports.pp$1.parseBlock (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19157:23)
    at Object.module.exports.pp$1.parseTryStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19073:24)
    at Object.module.exports.pp$1.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:18834:32)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4539:118)
    at Object.parseStatement (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:42314:22)
    at Object.module.exports.pp$1.parseBlock (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:19157:23)
    at Object.module.exports.pp$3.parseFunctionBody (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20675:22)
    at Object.module.exports.pp$3.parseArrowExpression (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20638:8)
    at Object.module.exports.pp$3.parseExprAtom (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20227:21)
    at Object.parseExprAtom (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@marshallofsound
/webpack-asset-relocator-loader/dist/index.js:4551:117)
    at Object../node_modules/fs-extra/lib/mkdirs/make-dir.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:77510:7)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/mkdirs/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:77487:44)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/copy-sync/copy-sync.js (/home/marco/webMatters/electronMatters/IpfsPlaying
/.webpack/main/index.js:76425:20)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/copy-sync/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:76602:13)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:77353:6)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)

So.. how to concretely resolve the issue?

You can find the code here: https://github.com/raphael10-collab/IpfsPlaying

achingbrain commented 3 years ago

I'm not sure, you're getting a syntax error but it doesn't say where.

I see you've got @marshallofsound/webpack-asset-relocator-loader in there, this may be relevant: https://github.com/electron-userland/electron-forge/issues/1327#issuecomment-562894342

raphael10-collab commented 3 years ago

@achingbrain

I started from a brand new working very simple Electron-Typescript app which does not contain any reference to the @marshallofsound/webpack-asset-relocator-loader and to any asset-reloactor-loader.

In this working really simple Electron-Typescript app, I added in main.ts:

import Ipfs from 'ipfs';
import IpfsHttpClient from 'ipfs-http-client';

and this import of ipfs modules went fine.

But when I add

const { globSource } = IpfsHttpClient;

or

when I create an IPFS node:

const ops = async () => {
  const node = await Ipfs.create({ repo: String(Math.random() + Date.now()) });
}

I get this error:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'jsonfile/utils'
    at webpackMissingModule (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:13356:87)
    at Object../node_modules/fs-extra/lib/json/output-json.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:13356:176)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/json/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:13284:25)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/fs-extra/lib/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:13250:6)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/ipfs-utils/src/files/glob-source.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:25171:12)
    at __webpack_require__ (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack/main/index.js:21:30)
    at Object../node_modules/ipfs-http-client/src/index.js (/home/marco/webMatters/electronMatters/IpfsPlaying/.webpack
/main/index.js:21670:20)

tools/webpack/webpack.main.js :

module.exports = {
  entry: ['./src/main.ts'],
  // Put your normal webpack config below here
  module: {
    rules: require('./webpack.rules'),
  },
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css', '.json'],
    alias: require('./webpack.aliases'),
  },
  target: 'electron-main'
};

tools/webpack/webpack.renderer.js :

/* eslint-disable @typescript-eslint/no-var-requires */
const rules = require('./webpack.rules');
const plugins = require('./webpack.plugins');
const aliases = require('./webpack.aliases');

module.exports = {
  target: 'electron-renderer',
  module: {
    rules,
  },
  plugins: plugins,
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'],
    alias: {
      // React Hot Loader Patch
      'react-dom': '@hot-loader/react-dom',
      // Custom Aliases
      ...aliases,
    },
  },
};

tools/webpack/webpack.rules.js :

const inDev = process.env.NODE_ENV === 'development';

module.exports = [
  {
    // Add support for native node modules
    test: /\.node$/,
    use: 'node-loader',
  },
  {
    // Typescript loader
    test: /\.tsx?$/,
    exclude: /(node_modules|\.webpack)/,
    use: {
      loader: 'ts-loader',
      options: {
        transpileOnly: true,
      },
    },
  },
  {
    // CSS Loader
    test: /\.css$/,
    use: [{ loader: 'style-loader' }, { loader: 'css-loader' }],
  },
  {
    // Less loader
    test: /\.less$/,
    use: [
      { loader: 'style-loader' },
      { loader: 'css-loader' },
      { loader: 'less-loader' },
    ],
  },
  {
    // Images Loader
    test: /\.(gif|jpe?g|tiff|png|webp|bmp)$/,
    use: [
      {
        loader: 'file-loader',
        options: {
          publicPath: 'images',
          outputPath: inDev ? 'images' : './main_window/images',
        },
      },
    ],
  },
];

If modify the target from electron-renderer' toweb' in tools/webpack/webpack.renderer.js :

/* eslint-disable @typescript-eslint/no-var-requires */
const rules = require('./webpack.rules');
const plugins = require('./webpack.plugins');
const aliases = require('./webpack.aliases');

module.exports = {
  //target: 'electron-renderer',
  target: 'web',
  module: {
    rules,
  },
  plugins: plugins,
  resolve: {
    extensions: ['.js', '.ts', '.jsx', '.tsx', '.css'],
    alias: {
      // React Hot Loader Patch
      'react-dom': '@hot-loader/react-dom',
      // Custom Aliases
      ...aliases,
    },
  },
};

And in the renderer process /src/app/components/App.tsx I add :

import Ipfs from 'ipfs';
const { globSource } = Ipfs;

const ops = async () => {
    const node = await Ipfs.create({ repo: String(Math.random() + 
Date.now()) });
    console.log('Ipfs node is ready');
    const files = [
      {
        path: '/home/marco/Downloads/Art21Costituzione.jpg',
        content: 'Art21Costituzione'
      },
      {
        path: '/home/marco/Downloads/VitaminaCAlimenti.pdf',
        content: 'VitaminaCAlimenti'
      }
    ];

    let results = await all(node.addAll(files));
    results.map(result => console.log(result));
}

I get this correct output:

image

But globSource in the renderer process gives error:

for await (const file of node.addAll(globSource('/home/marco/Downloads', globSourceOptions), addOptions)) {
  console.log(file);
}

image

How to solve the problem?

You can find the simple code in https://github.com/raphael10-collab/IpfsPlaying

raphael10-collab commented 3 years ago

@achingbrain in a nutshell: in the renderer process globSource doesn't work : globSource is not a function while in the main process I cannot even create an Ipfs node

So... how to make js-ipfs completely work in the renderer process , with target: 'web' in webpack configuration, and / or in the main process, with target: 'electron-main' in webpack configuration?

I posted the problem also here: https://discuss.ipfs.io/t/how-to-make-js-ipfs-completely-work-in-the-renderer-process-or-in-the-main-process-electron/10102

achingbrain commented 3 years ago

which does not contain any reference to the @marshallofsound/webpack-asset-relocator-loader and to any asset-reloactor-loader.

It's in the stack trace you posted:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Module build failed (from ./node_modules/@marshallofsound/webpack-asset-relocator-loader/dist/index.js):
SyntaxError: Unexpected token (85:14)
    at Object.module.exports.pp$4.raise (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules
/@marshallofsound/webpack-asset-relocator-loader/dist/index.js:20834:13) <<------ here

If modify the target from 'electron-renderer' to 'web'

If the target is web, it'll respect the browser property in package.json, which is used to exclude globsource from use in browsers as it uses node specific modules to read files from the filesystem, so it not being a function is expected when you're building for web browsers.

You should build your renderer process as electron-renderer and your main process as electron-main.

I get this error:

A JavaScript error occurred in the main process
Uncaught Exception:
Error: Cannot find module 'jsonfile/utils'

I see the same thing when I install the deps of your project and start it up.

There are two copies of jsonfile in my node_modules folder:

$ find . -type d -name jsonfile
./node_modules/jsonfile                          <-- v4.0.0
./node_modules/fs-extra/node_modules/jsonfile    <-- v6.1.0

The v6.1.0 has the utils module that cannot be found. fs-extra is used by globSource and it has a dependency on v6.1.0 not v4.0.0.

The question is, why is webpack loading the wrong one? The answer is likely to be somewhere between webpack, electron-forge and typescript.


I'm able to run the following:

$ npx create-electron-app my-app
$ cd my-app
$ npm install --save ipfs

Then edit src/index.js to start an IPFS node in the createWindow function, importing globSource etc without error, so I don't think this is an IPFS problem.

Your project has a ton of dependencies and build tools, some of which you aren't using. I'd remove everything and start from the basics.

There's a run-in-electron example that shows you a bare minimum setup. Maybe start with that and add in the extra tools one at a time until you find the thing that's breaking everything.

raphael10-collab commented 3 years ago

Thank you @achingbrain for having had a look at it.

As said, I've been using that simple working electron-typescript app, and till now I haven't encountered that error : Cannot find module 'jsonfile/utils'

Tomorrow morning I will be start from scatch again, with only webpack, electron-forge and typescript, which must be present in the app, and I will let you know my findings

raphael10-collab commented 3 years ago

@achingbrain may I ask you a suggestion?

I removed all extra stuff and what is left now is what I consider a bear minimum:

{
  "name": "IpfsPlaying",
  "version": "2.0.2",
  "description": "IpfsPlaying",
  "main": ".webpack/main",
  "scripts": {
    "start": "cross-env NODE_ENV=development electron-forge start",
    "package": "electron-forge package",
    "make": "electron-forge make",
    "publish": "electron-forge publish",
    "lint": "eslint --ext .ts ."
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/raphael10-collab/IpfsPlaying"
  },
  "license": "MIT",
  "config": {
    "forge": "./tools/forge/forge.config.js"
  },
  "devDependencies": {
    "@electron-forge/cli": "^6.0.0-beta.54",
    "@electron-forge/maker-deb": "6.0.0-beta.53",
    "@electron-forge/maker-rpm": "6.0.0-beta.53",
    "@electron-forge/maker-squirrel": "^6.0.0-beta.54",
    "@electron-forge/maker-zip": "6.0.0-beta.53",
    "@electron-forge/plugin-webpack": "6.0.0-beta.53",
    "@types/react": "^16.9.49",
    "@types/react-dom": "^16.9.8",
    "@types/webpack-env": "^1.15.2",
    "@typescript-eslint/eslint-plugin": "^4.1.1",
    "@typescript-eslint/parser": "^4.1.1",
    "copy-webpack-plugin": "6",
    "cross-env": "^7.0.2",
    "electron": "^10.1.2",
    "eslint": "^7.9.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-plugin-import": "^2.20.0",
    "eslint-plugin-react": "^7.20.6",
    "fork-ts-checker-webpack-plugin": "^5.2.0",
    "less": "^3.12.2",
    "node-loader": "^1.0.1",
    "react-hot-loader": "^4.12.21",
    "ts-loader": "^8.0.3",
    "typescript": "^4.0.2",
    "webpack": "4"
 },
 "dependencies": {
    "@hot-loader/react-dom": "^16.13.0",
    "ipfs": "^0.54.1",
    "ipfs-http-client": "^49.0.1",
    "ipfs-utils": "^6.0.0",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-viewer": "^3.2.2",
    "react-window": "^1.8.6"
  } 
}

These are the modules which depend on jsonfile :

(base) marco@pc01:~/webMatters/electronMatters/IpfsPlaying$ npm ls jsonfile
IpfsPlaying@2.0.2 /home/marco/webMatters/electronMatters/IpfsPlaying
├─┬ @electron-forge/cli@6.0.0-beta.54
│ ├─┬ @electron-forge/core@6.0.0-beta.54
│ │ └─┬ electron-packager@15.2.0
│ │   └─┬ galactus@0.2.1
│ │     ├─┬ flora-colossus@1.0.1
│ │     │ └─┬ fs-extra@7.0.1
│ │     │   └── jsonfile@4.0.0  deduped
│ │     └─┬ fs-extra@4.0.3
│ │       └── jsonfile@4.0.0  deduped
│ ├─┬ @electron/get@1.12.2
│ │ └─┬ fs-extra@8.1.0
│ │   └── jsonfile@4.0.0 
│ └─┬ fs-extra@9.0.1
│   └── jsonfile@6.1.0 
└─┬ @electron-forge/maker-squirrel@6.0.0-beta.54
  └─┬ electron-winstaller@4.0.1
    └─┬ fs-extra@7.0.1
      └── jsonfile@4.0.0  deduped

But there is another jsonfile, which is used by Ipfs:

(base) marco@pc01:~/webMatters/electronMatters/IpfsPlaying$ find . -type d -name jsonfile
./node_modules/jsonfile <--v4
./node_modules/fs-extra/node_modules/jsonfile <--- v6 used by Ipfs

Why this jsonfile ./node_modules/fs-extra/node_modules/jsonfile does not appear when searching all jsonfile modules?

If I remove the jsonfile v4 I get the error: "An unhandled exception has occured inside Forge":

(base) marco@pc01:~/webMatters/electronMatters/IpfsPlaying$ rm -rf ./node_modules/jsonfile/
(base) marco@pc01:~/webMatters/electronMatters/IpfsPlaying$ yarn start
yarn run v1.22.5
$ cross-env NODE_ENV=development electron-forge start

An unhandled exception has occurred inside Forge:
Cannot find module 'jsonfile'
Require stack:
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/json/jsonfile.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/json/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/utils.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/artifact-utils.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/core/dist/api/make.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/core/dist/api/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/cli/dist/util/check-system.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/cli/dist/electron-forge.js
Error: Cannot find module 'jsonfile'
Require stack:
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/json/jsonfile.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/json/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules/fs-extra/lib/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/utils.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/artifact-utils.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/dist/cjs/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/core/dist/api/make.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/core/dist/api/index.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/cli/dist/util/check-system.js
- /home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron-forge/cli/dist/electron-forge.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:1030:15)
    at Function.Module._load (internal/modules/cjs/loader.js:899:27)
    at Module.require (internal/modules/cjs/loader.js:1090:19)
    at require (internal/modules/cjs/helpers.js:75:18)
    at Object.<anonymous> (/home/marco/webMatters/electronMatters/IpfsPlaying/node_modules/@electron/get/node_modules
/fs-extra/lib/json/jsonfile.js:4:18)
    at Module._compile (internal/modules/cjs/loader.js:1201:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1221:10)
    at Module.load (internal/modules/cjs/loader.js:1050:32)
    at Function.Module._load (internal/modules/cjs/loader.js:938:14)
    at Module.require (internal/modules/cjs/loader.js:1090:19)

Since Electron-Forge is a utility which , as far as I understand, helps in developing complex Electron apps, what do you suggest me to do ?

achingbrain commented 3 years ago

I suggest you start from the run-in-electron example which gives you a minimal setup for running IPFS under electron, then add your extra dependencies/build tools one by one until you start seeing errors.