javascripttypescriptipfsorbitdb

import javascript module: The requested module X does not provide an export named Y


I am having a problem to import some of the content of a JavaScript module (ipfs). Here is the code (test.js), taken from OrbitDB Module with IPFS Instance that I am trying to run from the command line as a node app (node test.js):

import IPFS from 'ipfs'
import OrbitDB from 'orbit-db'

;(async function () {
  const ipfs = await IPFS.create()
  const orbitdb = await OrbitDB.createInstance(ipfs)

  // Create / Open a database
  const db = await orbitdb.log("hello")
  await db.load()

  // Listen for updates from peers
  db.events.on("replicated", address => {
    console.log(db.iterator({ limit: -1 }).collect())
  })

  // Add an entry
  const hash = await db.add("world")
  console.log(hash)

  // Query
  const result = db.iterator({ limit: -1 }).collect()
  console.log(JSON.stringify(result, null, 2))
})()

When I run this code from the command line with node, it throws the following error:

import IPFS from 'ipfs'
       ^^^^
SyntaxError: The requested module 'ipfs' does not provide an export named 'default'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:127:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:193:5)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12)

Process finished with exit code 1

I tried to find out what is wrong here. So I ctrl-clicked on ipfs and it takes me to the following index.d.ts:

/**
 * @typedef {import('ipfs-core-types').IPFS} IPFS
 */
export const create: typeof import("ipfs-core/src/components").create;
export const crypto: typeof import("libp2p-crypto");
export const isIPFS: typeof import("is-ipfs");
export const CID: typeof import("multiformats").CID;
export const multiaddr: typeof import("multiaddr").Multiaddr;
export const PeerId: typeof import("peer-id");
export const globSource: typeof import("ipfs-utils/src/files/glob-source");
export const urlSource: typeof import("ipfs-utils/src/files/url-source");
export const path: typeof pathImport;
export type IPFS = import('ipfs-core-types').IPFS;
import { path as pathImport } from "./path.js";
//# sourceMappingURL=index.d.ts.map

It looks to me like IPFS is exported by a named export. So I tried to change my code to named import, like this:

import {IPFS} from 'ipfs'

This throws the following error:

import {IPFS} from 'ipfs'
        ^^^^
SyntaxError: The requested module 'ipfs' does not provide an export named 'IPFS'
    at ModuleJob._instantiate (node:internal/modules/esm/module_job:127:21)
    at async ModuleJob.run (node:internal/modules/esm/module_job:193:5)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:337:24)
    at async loadESM (node:internal/process/esm_loader:88:5)
    at async handleMainPromise (node:internal/modules/run_main:61:12)

Process finished with exit code 1

So how can I solve this problem?

Here is the package.json that I have together with test.js:

{
  "name": "ipfs-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",  
  "type": "module"
}

I should mention that I wrote the code in Intellij, and it did not show a compilation error, which it usually does when it cannot locate imports. So that's also weird.


Solution

  • There is no default export (export default somethingSomething) so using import IPFS from 'ipfs' won't work.

    You are half-right that a named export IPFS is there, however you looked at a TypeScript definition file, and the export named IPFS is just a type in TypeScript and not anything JavaScript even sees.

    Instead, you can see that the create method you used in IPFS.create is a named export, so import { create } from 'ipfs' would work, but in fact you can keep your code that uses IPFS.create and simply change import IPFS from 'ipfs' to import * as IPFS from 'ipfs'!

    The import * as something from 'something' syntax will give you an object with all named exports inside.