Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Repos, repos, repos #2446

Closed
Closed
@achingbrain

Description

@achingbrain

Making changes in js-ipfs typically involves changing this repo, the ipfs-http-client, interface-js-ipfs-core and also ipfds-ctl (because of it's dependency on ipfs-http-client.

We have these as separate modules but they are really modular in name only due to the cross-dependencies indicated above.

This has had a number of consequences:

  1. Developers have to coordinate PRs across all of these repos which is painful for experienced contributors and completely bewildering for new contributors
  2. It's impossible to have one PR that encapsulates a changeset - this makes it hard to test, hard to review, hard to integrate, hard to release and hard to roll back
  3. There is no one build that says "Yes, this change is ok" which results in a lot of manual work and makes automation harder because you have to juggle multiple versions of multiple modules
  4. There is a large amount of duplication across these repos, from tests to utility methods (js-ipfs-utils is helping with the utility methods but is also compounding the problem).
  5. Coordinating shared dependency updates across these modules becomes a Byzantine task (e.g. see how out of date libp2p, ipld, are at the moment etc)

Since this project does not include the libp2p and IPLD codebases it should be a relatively thin layer on top of them, yet development is very complex.

We've started talking about re-integrating some core modules in #2222 but we should go further than that.

⚒️ Break the ipfsd-ctl/ipfs-http-client dependency

Possible solutions:

a. Make ipfs-http-client a peer dependency of ipfsd-ctl
b. Require an implementation to be passed in the same way as with in-proc js-ipfs daemons

💍 One PR to rule them all

Combine the repos. One way to do this might be adding the client/ipfsd to core:

const IPFS = require('ipfs')
const IPFSClient = require('ipfs/client')

...

✅ Pro: Simple to use
✅ Pro: Works with existing unspecified tooling that assumes one-module-per-repo
❌ Con: If you only consume the client you'll end up installing lots of dependencies you don't need
❌ Con: Separate PRs to interface-js-ipfs-core still required unless you add that in too
❌ Con: Poor separation of concerns
❌ Con: All-or-nothing releases

Another way might be a lerna-style mono-repo a la babel:

$ ls -l
js-ipfs/
├── package.json
├── lerna.json
└── packages/
    ├── ipfs
    ├── ipfsd-ctl
    ├── ipfs-http-client
    └── interface-js-ipfs-core

✅ Pro: One change, one PR
✅ Pro: Existing dependant code does not break because module names do not change
✅ Pro: Still able to release individual modules independently
✅ Pro: Easier to make, review and release changes
✅ Pro: Easier to contribute to
✅ Pro: The tooling figures out cross-package dependencies, no more npm link required
✅ Pro: Clever enough to figure out which package depends on which and only test/release what's changed
❌ Con: In the worst case tests take as long as the slowest module
❌ Con: Cannot group GH issues by package
❌ Con: Tools that assume one-module-per-repo will need fixing
❌ Con: When adding new dependencies, it's easy to forget to add them to the right package due to dependency hoisting

cc @ipfs/wg-js-core and @ipfs/repos-javascript

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions