2

We have an Angular library where we have multiple modules. Each module can be imported and used independently in parent projects. In one of those modules' component we have an import from a dependency called "libphonenumber-js", which we tried to declare as optional, but the parent projects still need to declare this dependency in their package.json, even if they do not import this module.

This is the error on parent projects without having this dependency: Error: Module not found: Error: Can't resolve 'libphonenumber-js' in

And thelibrary's package.json looks like this:

 "peerDependencies": {
    "@angular/animations": ">=14.1.0",
    "@angular/cdk": ">=14.1.0",
    "@angular/common": ">=14.1.0",
    "@angular/core": ">=14.1.0",
    "@angular/forms": ">=14.1.0",
    "@types/bootstrap": "^5.2.0",
    "@types/jquery": ">=3.5.14",
    "@types/lodash-es": ">=4.17.6",
    "dayjs": ">=1.11.4",
    "jquery": ">=3.6.0",
    "libphonenumber-js": ">=1.10.9"
    ...
  },
  "peerDependenciesMeta": {
    "libphonenumber-js": {
      "optional": true
    }
  },

We have npm version 8.5.0 and the node version 16.14.2.

Probably we did not define the optional dependency properly.. Can you help?

JSON Derulo
  • 9,780
  • 7
  • 39
  • 56
akcasoy
  • 6,497
  • 13
  • 56
  • 100

1 Answers1

3

If one of your module has dependencies which the others don't have, and if you mark this dependencies as optional, you have to use secondary entrypoints. During build, the TypeScript compiler goes over the type declaration file of all the used entrypoints and will throw errors in case something is wrong.

You could either create a secondary entrypoint per module, or keep your "big" entrypoint and just extract the problematic module into its own entrypoint.

To create and configure a secondary entrypoint, just create a directory with the name of the entrypoint add a ng-package.json file to the directory with the content {}.

JSON Derulo
  • 9,780
  • 7
  • 39
  • 56
  • thank you! in case you have some experience with entrypoints: do you think that makes sense to create an entrypoint for each module? So the parents would only need to import a specific entry point they are interested in, instead of the entire library... At the moment our library contains i.e. 20 components, and each component is defined in its own module, so that the parents can import those separately. – akcasoy Apr 28 '23 at 09:02
  • @akcasoy My opinion on that: I think it makes sense to create an entrypoint per module, because entrypoints are a strict separation. If there is an issue in one module (i.e. TypeScript errors due to outdated "lib" in tsconfig, a real issue I had in the past), it can easily affect all the other modules as well. With separation into different entrypoints, I'm only affected if I actually use the module, otherwise everyone would be affected. The Angular team itself also creates an entrypoint per module in their `@angular/material` package. – JSON Derulo Apr 28 '23 at 09:14