Nrwl Nx: different version numbers and libs
Asked Answered
S

5

22

I want to start an Angular project using Nrwl Nx (multiple apps in one project; https://nrwl.io/nx), but I have two questions:

  1. How can I specify different version numbers to the different apps? Usually I give a version number in package.json, but with Nx there are only one package.json for all of my apps. Should I put it in the environment files? Or in the .angular-cli.json file?

  2. I read this: 'An upgrade to a lib requires a change to all implementors.' Is there any solution (bypass) to use different versions of a lib or NPM package in different apps? There is only one node_modules, but this is critical for my apps.

As you know, the structure of an Nx project looks like this:

apps
    app1
    app2
libs
    lib1
    lib2
node_modules
package.json
.angular-cli.json
...

Maybe these two questions are a little bit opinion-based (I'm not so sure about that tbh), but there are very few articles about Nrwl Nx, and the answers can help others too. Thank you.

Sunglass answered 6/3, 2018 at 13:21 Comment(4)
Hi, did you come up with some kind of solution? I would say I have the same "issue". In my case, app1 and app2 could use a different version of lib1.Kynewulf
@BrunoBruzzano Hi, not really. Maybe check this one out: github.com/nrwl/nx/issues/309Stunner
lol, I have asked there already but I didnt get any reply at all :-(Kynewulf
None of these answers are really answers, but rather just "don't do that" comments. Unfortunately, this is inadequate for a lot of situations. For instance, I have a monorepo of multiple small-ish APIs. Each one of these needs to be semantically versioned, meaning that a shared version makes no sense in regards to individual changes. I'd love to hear from anyone who has an actual solution to the question asked.Houseyhousey
M
11

I have some ideas here. I work with the NX Extensions every day, and IMHO, leaning on, "that's not the mono repo way" is fine as an ideal but fails in practice. You WILL sooner or later want to make a breaking change to a lib, and you don't want all your tests in the apps failing when you do it (prevent you from releasing, etc, which you may not have the luxury of time to clean up). This might not be exactly what the OP is getting at, but I think with a little change in thinking these solutions might serve. I've tried 'em all, they seem to work.

Note that I am aware of the google way (I worked there). I ran into this problem on the first project I worked on. Their dev environment provides an analog of "if you could have different package.jsons in each app..." so comparing NX to Google's internal system as an absolute 1:1 is a bit off.

Qualifier: this is not "the answer". It just shares some ways I've overcome these problems.

  • Branch the entire repo, call it a version. Make your breaking change, see it all fall apart. Fix everything, update from master, looks good, merge it. Optional: release from this branch.

That "devbranch" thing works for most "breaking lib change" kind of things.

  • In tsconfig.json, provided you aliased your library (@myorg/blah), your app will point at the path you configure. In master, build your lib (ng-packagr). Using the output config, you can call the dist whatever you want (@myorg/blah-v1, v2, as many as you want). Point tsconfig at it (tsconfig will be pointing to the non-build path). Master will now use a locked, known version of the lib (just DON'T REBUILD IT WITH CHANGES). You are now free to abuse your master library as you see fit. To keep an "everything in master working" mindset, you would branch master and then make this change, which would allow you to work on the lib independent of the apps that use it with master untouched.

  • Build your library (versioned, and assumes ng-packagr), npm pack it (you now have a tarball), do what you want with it. Branch master, remove the path entry from tsconfig, add an install entry to package.json (you can install from a file), and your apps should pick it up (again, the import aliases should match). You can also do the install in master (known working version as a tarball), and again abuse your libs as you want.

That latter solution I tested a little and I saw it works, but if you don't have to pack a tarball and mess with package.json, why bother. Good option to know though, and it doesn't incur the downside of not being able to rebuild the library (as you'll overwrite the known working version unless you change the output target).

Using these ideas, I can pretty much get us out of any breaking change jam and provide at least provide one other known working version of any given lib.

I'll put these out there too though:

A primary benefit of a mono repo is that it forces you to avoid incurring the technical debt that multiple lib versions cause, which is SEVERE if you let it go for any period of time. If you let it go long enough, sooner or later you'll have problems with the overall version of Angular, which is a problem you WANT to avoid.

If it gets to the point that you have an app that requires a lot of drift, IMHO, you'd be best served by creating a new repo, dumping the code into it, wiping it from your main repo, wait until it gets into shape, and put it back when it's ready (if ever).

And, remember, when you are working on a library, you need to think a bit differently. It's shared code, and every time you make a change to it, it can't be breaking. Instead of renaming that input, create another one and point it at the original (backward compat), and that sort of thing. Decorator patterns, all that. A breaking change in a lib should NOT be a casually committed thing.

Hope that helps.

Mcclellan answered 24/8, 2020 at 18:24 Comment(1)
I do hope it helps. I see no reason to edit that out. If you're going to edit please provide me a reason.Mcclellan
T
4

Technically it is not possible to specify different version numbers to the different apps in NX workspace, because NX workspace is based on monorepo (It is a technology used by leading IT company such as google, Facebook etc).

Yes, you can specify different version numbers to the different apps by restructuring the NX workspace, but then technically it will not be a monorepo NX workspace.

Telemechanics answered 25/2, 2019 at 12:15 Comment(0)
A
3

As JBecton already replied, the "Nx way" is to have one package.json.

In your case you need to dis-associate your app versioning from the mono-repo versioning.

The angular generated environment*.ts files is the right place to do this.

Amur answered 28/6, 2018 at 9:42 Comment(1)
I gotta say this make the most sense to me. Although I see the value of having the same node_modules and package.json, the use case of managing version numbers independently for each application is definitely needed.Methylnaphthalene
K
-1

As per Monorepo concept all the application should come in the same umbrella that means in the same repository and to maintain multiple application in the same monorepo it is very difficult with different versions. Also having one package file ensure that while updating workspace all the applications are updating by default. Which should be the standard for any organization to have all application in the same version.

Katha answered 14/9, 2019 at 7:10 Comment(0)
R
-2

Nx uses a MonoRepo approach so your apps and libraries will all be the same version. https://nrwl.io/nx/why-a-workspace

Ronel answered 17/4, 2018 at 18:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.