angularnpmnode-modulesng-packagr

How to declare a dependency as optional in an Angular Library?


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?


Solution

  • 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 {}.