6

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.

David Fariña
  • 1,536
  • 1
  • 18
  • 28

3 Answers3

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.

David Fariña
  • 1,536
  • 1
  • 18
  • 28
-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.

-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

  • 1
    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 peerDependency – David Fariña Jul 20 '21 at 09:56
  • 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. – Aleksandr Smyshliaev Jul 20 '21 at 10:00
  • 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 it – David Fariña Jul 20 '21 at 10:03