IPFS and Vue; dependency not found

I’m using IPFS with Vue but cannot get the app to start because of a dependency error.

I have a very simple setup:

vue create my-project 
cd my-project 
npm install ipfs

Import ipfs in some component:

import * as IPFS from "ipfs";

and run

npm run serve

and it will error with:

This dependency was not found: * ipfs in ./node_modules/cache-loader/dist/cjs.js??ref--13-0!./node_modules/babel-loader/lib!./node_modules/cache-loader/dist/cjs.js??ref--1-0!./node_modules/vue-loader/lib??vue- loader-options!./src/components/ProfileEditor.vue?vue&type=script&lang=js& 

To install it, you can run: npm install --save ipfs

However, I already have ipfs installed.

I can get this working with vanilla node but for some reason vue cannot load this package.

Have a look at the examples GitHub - ipfs-examples/js-ipfs-examples: Collection of js-ipfs examples specifically the vue example: js-ipfs-examples/examples/browser-vue at master · ipfs-examples/js-ipfs-examples · GitHub

Thanks for the suggestion.

So, yes, I’m able to get the vue example running and I’m also able to use ipfs-core from a vanilla node install. However, I’m confused why I can’t simply get IPFS running by installing the package and then importing it. Comparing my out-of-the-box vue project with the example suggests the only difference is importing the minimal package ipfs-core. I tried this but got another round of dependency issues:

These dependencies were not found:

* @libp2p/crypto/keys in ./node_modules/ipfs-core/src/components/storage.js, ./node_modules/ipfs-core/src/components/name/publish.js and 1 other
* @libp2p/interfaces/peer-id in ./node_modules/ipfs-core/src/components/storage.js, ./node_modules/ipfs-core/src/ipns/publisher.js
* @libp2p/logger in ./node_modules/ipfs-core/src/preload.js, ./node_modules/ipfs-core/src/components/index.js and 8 others
* @libp2p/peer-id in ./node_modules/ipfs-core/src/components/resolve.js, ./node_modules/ipfs-core/src/components/name/publish.js and 2 others
* @libp2p/peer-id-factory in ./node_modules/ipfs-core/src/components/storage.js
* @libp2p/record in ./node_modules/ipfs-core/src/ipns/routing/offline-datastore.js
* @libp2p/topology in ./node_modules/ipfs-bitswap/src/network.js
...

This would suggest some kind of import error (maybe webpack related) because those packages are available but it seems they are not getting imported.

Migrating an existing vue app to a browser-vue-based example boilerplate is not really viable unfortunately.

I’m not sure why simply installing ipfs and then importing is creating so many dependency errors. It must be a configuration issue but where?

Looking into this further, it seems to be some kind of import misconfiguration, for example, this import error:

These dependencies were not found:

* @libp2p/crypto/keys in ./node_modules/ipfs-core/src/components/storage.js, ./node_modules/ipfs-core/src/components/name/publish.js and 1 other

@libp2p is installed and crypto/keys exists under @libp2p/crypto/src/keys. I suspect the “src” is causing the problem but am unsure how to resolve.

So, turns out I was setting up my project incorrectly in Vue. Running npm init vue@3 (or vue@2) is the correct way to deploy a new project. Doing this and installing ipfs-core gets rid of the above error and opens up a whole new list of errors:

ERROR] Big integer literals are not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari13" + 2 overrides)

    node_modules/ipfs-core/src/ipns/publisher.js:193:20:
      193 │     let seqNumber = 0n

All errors are related to this lack of support for native big number and my understanding is esNext addresses it. However, I’m at a loss how to fix.

This is solvable by configuring native bigint support in vite.config.js :

esBuildOptions {
      supported: { 
        bigint: true 
      }
}

but this just cascades into a new error:

index.js:88 Uncaught ReferenceError: global is not defined
    at node_modules/ipfs-repo/node_modules/mortice/lib/index.js (index.js:88:3)

This can apparently be solved with:

esbuildOptions: {
      define: {
        global: 'globalThis'
      }
}

but this just results in another error:

browser-external:util:9 Uncaught Error: Module "util" has been externalized for browser compatibility. Cannot access "util.inherits" in client code.

I’m at a loss as to how I can’t just install the ipfs package and start using it, a la the documentation. This is feeling like it is fundamentally broken.

The following fixed all my problems and I was able to get Vue + IPFS working.

Create a vue project:

npm init vue@2

or

npm init vue@3

Install IPFS:

npm i ipfs-core

Add native bigint support to vite.config.js file:

  optimizeDeps: {
    esbuildOptions: {
      supported: { 
        bigint: true 
      }
    }
  }

Install util:

npm i --D util

Deep in the IPFS libs there are server features which vite doesn’t support. Add the following to vite.config.js, directly under the config object:

export default defineConfig({
  define: {
    "process.env": {}
  },

Finally, add support for process to esbuildOptions (vite doesn’t support the process object by default):

define: {
  global: 'globalThis'
}

Finally, include ipfs in one of the vue files:

import * as IPFS from "ipfs-core"

Now run npm run dev and IPFS should work without issue.