How to make optional peer dependencies truly optional
Asked Answered
B

3

7

I have an NPM package that offers two things: Core functionality in form of React hooks and UI components that use these core functionalities.

My idea originally was to make two packages, one for the core stuff and one for the components. So that if you don't want to use the components out of the box, you could still use the libraries core features. After working on the library I found it to be overkill to make two packages, because the core functionality is basically 2 Hooks with less than 200 lines of code.

So I went the route to add the UI components dependencies as peer dependencies, and expected that when I mark them as optional, you wouldn't need to install them if you don't need the UI parts. With mark them as optional I mean:

"peerDependenciesMeta": {
    "@material-ui/core": {
      "optional": true
    },
}

Now the problem is, even if I don't import the UI parts from my library into a testing project I set up, the App breaks because it is trying to look for the optional dependencies.

My questions:

  • Is this expected behavior?
  • Whats optional about these peer dependencies, if the App breaks when the modules my library depends on are not around?
  • Are there no options for me other than to make a separate package for the components?

Hopefully someone can shed some light into the dark for me.

Benoni answered 20/7, 2021 at 8:56 Comment(1)
Which NPM version are you using? Can you provide the error message? I'm facing a similar issue.Nankeen
B
0

Seems the only real solution to this is to really split the core functionality from the UI parts. Otherwise, there will be always dependencies installed that a user might not want.

Benoni answered 23/7, 2021 at 13:19 Comment(0)
S
-2

peerDependencies are not optional, it's packages that library uses but they not bundled with library code.

E.g. if have react component library, react and react-dom are peerDependecies, mean library need them to work but they should not be bundled with library components.

So when you use library in your app it uses React package from app not from library itself.

Sustenance answered 20/7, 2021 at 9:3 Comment(7)
Maybe I wasn't clear. I understand peer dependencies themself are not optional and I get the idea behind it, but I marked them as optional like this: "peerDependenciesMeta": { "@material-ui/core": { "optional": true }, }Epicarp
Maybe try to use optionalDependencies then?Sustenance
I'm not sure this is what I need. The idea was to have the UI dependencies as peers so that it doesn't get installed if the project that uses my library already has them installed.Epicarp
Maybe describe version range "peerDependencies": { "@material-ui/core": "^15.x || ^16.x || ^17.x" }, Can google about version notation.Sustenance
What if you don't want to use the UI libary? It will be installed anyway right?Epicarp
It will be installed anyway, but if you don't use the UI library it will not be bundled.Sustenance
This seems like a viable solution. Could you create a new answer for this so I can accept it?Epicarp
S
-2

Ok, so library use that dependencies, you just wanna that it use existing version of it that installed in main App.

Can specify version of deps not so strictly

"peerDependencies": { "@material-ui/core": "^15.x || ^16.x || ^17.x" }

Or

"peerDependencies": { "@material-ui/core": "15.x - 17.x" }

Versioning

Sustenance answered 20/7, 2021 at 9:48 Comment(3)
But this means the material UI has to be installed. The idea was to have it optional. If I import {coreFunction} from "mylibrary" I dont need material UI. If I import {UIComponent} from "mylibrary" I should need to have it installed. Kind of like an optional peerDependencyEpicarp
Library use materialUI so it should be installed. Optional if UIComponent can work fine without materialUI at all. If tree shaking works there is no problem.Sustenance
It only uses material UI for the components, not for the core functionality. If you only want core functionality then it isn't needed to install material UI. At least thats what I hoped for. Maybe I really need to make a second package for itEpicarp

© 2022 - 2024 — McMap. All rights reserved.