Support for import of non-buildable libraries in buildable libraries

See original GitHub issue

Description

Currently, it is not possible to import a non-buildable library in a buildable library.

image

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:

  1. I open the door for version mismatches, e.g. because a user of my library updates A, but forgets to update c. This is all solvable somehow, but why would I even want to deal with this problem, if I could just bundle the code of c with A and B?
  2. 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:closed
  • Created 3 years ago
  • Reactions:32
  • Comments:10

github_iconTop GitHub Comments

8reactions
Bogs-123commented, May 3, 2021

We ran into the same error. There is a lot of added value in this.

0reactions
Amith-Bcommented, Dec 15, 2022

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:package as 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:package as executor.

Read more comments on GitHub >

github_iconTop Results From Across the Web

nrwl-nx/community - Gitter
... I'm getting an error with buildable libs cannot import non-buildable libs . ... @lioman, in order to create a new library with...
Read more >
Buildable and Publishable Libraries - Nx
The --buildable and --publishable options are available on the Nx library ... Your import path is the actual scope of your distributable package...
Read more >
New buildable angular library can not be build - Stack Overflow
Even when I add components and export them or import the module in an app, the error shows up. What am I missing...
Read more >
Taming Code Organization with Module Boundaries in Nx
Finally, the flag enforceBuildableLibDependency prevents us from importing a non-buildable library into a buildable one. You can read more ...
Read more >
Effective React Development with Nx
In chapter 2 we build new libraries to support a book listing feature. ... import { render, cleanup } from '@testing-library/react';.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found