Support for import of non-buildable libraries in buildable libraries
See original GitHub issueDescription
Currently, it is not possible to import a non-buildable library in a buildable library.

I think there are valid use cases for wanting to import non-buildable libraries in buildable libraries (see Motivation) and that therefore this should be supported by Nx (see Motivation)
Motivation
As explained by @jaysoo in this comment, this is a conscious decision by the Nx team:
I’m going to close this issue since we will not be supporting imports of non-buildable libraries from buildable ones. Instead, dependencies should be made buildable as well. This constraint makes sense if you think about shared libraries between two buildable parents.
In ECMAScript/TypeScript a module is a file. That is the highest level of modularization with strict encapsulation offered on a language level. The only way to get something like “package-level” encapsulation is by using npm packages (and even that may not prevent deep imports). In large projects, I need something in between: coarser-grained than a file, but without the overhead of managing an npm package.
I started using Nx when it was still very much based on Angular, at a time when Angular didn’t even support building libraries out of the box, and I have been convincing a lot of my colleagues to use Nx in their projects. For one simple reason: Libraries in Nx along with the enforce-module-boundaries linting rule provide me with the “package-level” encapsulation mechanism the JS/TS ecosystem is missing.
I cannot stress this enough: The main reason for me to use Nx Workspace is the ability to modularize my project into separate libraries with clear APIs and strict encapsulation. I’ve seen countless unmaintainable Angular monoliths and I have refactored more than one of these monoliths into well-modularized, maintainable projects with the help of Nx. And now that you guys added support for Non-Angular projects, I can even use this to modularize my React or NestJS app.
Computation caching, Storybook/Jest/Cypress support, etc. - all that is nice, but without libraries and enforce-module-boundaries I don’t think I would use Nx in most of my projects.
Why do I tell you all of this? Because the decision not to support the import of non-buildable library in a buildable library ignores the fact, that libraries are used by many projects to organize their code.
Let’s have a look at an example:
I have two publishable libraries (A and B) in my workspace. Both depend on shared code in library c.
According to the decision of the Nx team, I need to publish library c as well. This means, when someone wants to use library A, he/she also needs to install library c. That is not only inconvenient, it comes with to problems:
- I open the door for version mismatches, e.g. because a user of my library updates
A, but forgets to updatec. This is all solvable somehow, but why would I even want to deal with this problem, if I could just bundle the code ofcwithAandB? - I expose what should be an implementation detail: the dependencies between modules of my project.
I saw a lot of discussions about 1. and I think both sides have valid arguments - so why not let the developer decide which way to go?
But for me, 2. is even more important. I do not want to expose the inner workings of my library to external users. What happens if at some point I decide to split c into c1 and c2? Then all users of my library need to update their dependencies because I decided to do some refactoring that may not even change the behavior of the library.
Suggested Implementation
In Angular-land this may be not as as easy as it seems as ng-packagr seems to have a hard-coded rootDir matching the entryPoint. As for non-Angular libraries, I have no idea 🤷🏻♂️
Alternate Implementations
Find a way to use enforce-module-boundaries without Nx, but who wants that…? 😉
Issue Analytics
- State:
- Created 3 years ago
- Reactions:32
- Comments:10
Top Related StackOverflow Question
We ran into the same error. There is a lot of added value in this.
I have similar issue, still wasn’t able to find a way to fix this, there are 2 libraries a (with angular) and b (with react), and a util library c which is used in both a and b. When a or b is built, the code of c should be present in both the builds.
The react library(b) which uses
@nxext/vite:packageas executor works fine as it bundles the code of c in it’s build, but I am facing issue with angular library(a) build which is using@nrwl/angular:packageas executor.