Using Angular cache with library
Tags: angular, npm, verdaccio, library
Published: 2023-09-05 07:40:00

---
title: Using Angular cache with library
published: true
description: How the angular cache can interfere with the build of an application
tags: Angular, npm, verdaccio, library
# cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kl095eg7kug0p4rihhn3.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-09-01 15:56 +0000
---

![Angular cache and library](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kl095eg7kug0p4rihhn3.jpg)

How the angular cache can interfere with the build of an application.

I was reading this [nice article about Angular cache](https://balramchavan.medium.com/angular-cache-whats-inside-and-how-it-improves-angular-build-timing-on-local-and-ci-pipeline-f6821d22d67a) (starting with version 13), and it reminded me that I stumbled upon an issue with this feature regarding the development of libraries. Basically, if you install a library with npm, if the source code of the library changes **but not the version number**, what happens.

## The project
The Angular project we will be using consists of a workspace in which there will be a library and an application. Normally, when we develop an Angular library in the same workspace than the application, the local `tsconfig` file takes care of telling Angular where the source code is so that we don’t need to install the library.

For this project, we won’t be using the library directly, but we will publish it to any kind of registry compatible with npm and install it with npm install command.

I had 2 tools available :

* A free demo account with [jfrog.io](https://jfrog.com/start-free/) that allows you to host your Artifactory registry in the cloud. You get a domain name like `https://username.jfrog.io` and can publish right away.
* A local install of [Verdaccio](https://verdaccio.org/) running next to our app.

The first option is really nice to test, but it’s limited in time, and our actual needs for this demo are very simple and Verdaccio is more than enough.

## The local npm registry
Using verdaccio is very simple :

* Install the package globally :
```
npm install -g verdaccio
```
* Run verdaccio
```
verdaccio
```
You should see the server running :
![Local verdaccio registry running](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/98e641lovymumnyrq16w.png)
And access your empty registry (note these commands for using this registry for later) :
![verdaccio panel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/auxnptj076qp9f4gvg7u.png)
## The Angular workspace
Let’s create a very simple angular workspace and add a library and an application.
```
ng new ng-lib --create-application false
ng g application testapp
ng g library @abo/testlib
```
This way we have both projects in the workspace. Let’s remove the path configuration from the `tsconfig` file :
![Angular library path in tsconfig](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6bj7fbw93w7lwx2vfpdk.png)

This way, we will only use the library through the npm install, using our Verdaccio registry.

> Note : I’m aware that using an Angular library this way is not the proper way when you’re in `dev` mode but this is not the point here.

### Publish our library with npm
We must have followed the Verdaccio instructions to create the user we will login with. Then we can actually login, build the library and publish it :

```
npm login - registry http://localhost:4873/
Username: admin
Password:
Email: (this IS public) abo@abo.com
Logged in as admin on http://localhost:4873/.*
```

Building and publishing the angular library with the `publish:lib` script :
```json
"scripts": {
    "ng": "ng",
    "start:app": "ng serve testapp",
    "build:app": "ng build testapp",
    "build:lib": "ng build @abo/testlib",
    "publish:lib": "ng build @abo/testlib && cd dist/abo/testlib && npm publish --registry http://localhost:4873/",
    "watch": "ng build --watch --configuration development",
    "test": "ng test"
  },
```
The result must look like that : 
![Angular build of a local library and publish to registry](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/paow6qg05zzx0qyyduux.png)
And in our Verdaccio console, we should see the library added to the registry :
![Verdaccio angular published library](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9qbl368riyywe1y7u0ka.png)
### Add the library to the application
This is pretty easy, let’s clean up the code of the placeholder Angular application, install our library via the registry and add the single component exposed to our home page.
```
npm i @abo/testlib --registry http://localhost:4873/
...
+ @abo/testlib@0.0.1
added 1 package, removed 1 package and audited 992 packages in 8.988s
```

![The app.component with the library component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5t7d93g17uei9i3030mf.png)
Be careful when adding your library because some IDEs have an auto-import feature that is a little bit too fast to find the proper import. You could have something like that (and this would trigger application recompile when unwanted) :
```typescript
import { TestlibModule } from "../../../abo/testlib/src/lib/testlib.module";
```
When you would only want this :
```typescript
import { TestlibModule } from "@abo/testlib";
```
Let’s alter the library and publish a new version to see the changes. I don’t use any automatic semantic versioning system, let’s use simply the `npm version` command to upgrade the library and then re publish.
```
"scripts": {
    "upgrade-version:lib": "cd projects/abo/testlib && npm version patch",
    "publish:lib": "ng build @abo/testlib && cd dist/abo/testlib && npm publish --registry http://localhost:4873/",
```
Check that your library is up to date in Verdaccio and re install in your Angular workspace (the new 0.0.2 version).
```
npm i @abo/testlib@0.0.2 --registry http://localhost:4873/
```
The application should show the new library version :

![New angular library version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1x6hgbv0u5pqq66ykbt.png)

### Publish the same version of Angular library
Now, why would we want to publish the same version ? This could be a typical use case when you want to strictly control a release version, maybe aligned with a Maven package or something else. Anyway, let’s see what happens.

If you alter your code in the library and simply try to re publish it, you will get an error like this :

![npm publish package same version error](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b5ygu11cxnej350vuzv8.png)

Most of the npm registries prevent from publishing the same version, some allow you to set options to override, but I didn’t find the option in verdaccio — if anyone knows about it, feel free to say it in the comments.

Anyway, we will simply [unpublish the npm package](https://docs.npmjs.com/unpublishing-packages-from-the-registry) and re publish it.

```
"scripts": {
    "unpublish:lib": "npm unpublish @abo/testlib --registry http://localhost:4873/ --force",
```
So the tasks here are :

* Alter the library component
* Unpublish the library on Verdaccio
* Re build et re publish the library
* Uninstall / re install the library in our Angular workspace
* Run the application and see the result

![Still the same angular library version](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d1x6hgbv0u5pqq66ykbt.png)

Well, there is no difference, the application was built with a previous verison of the library. Yet, when we take a look at the `package-lock.json` we see that even if the version number is the same, the integrity property hash is different :

![Same npm version but different archive](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fssi49cx3atpg1l3iqgv.png)

And actually, if we take a look in the `node_modules/@abo/testlib` we see that the source code is the one we should expect :

![This is the proper updated source code of our Angular library](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dve13jr8c3xo2zwbx6dx.png)
So, what happend ? Well as you guessed, the angular cache is responsible for this, let’s see how we can act on this.

Remove the cache and then simply re start the application, which will force the build based on the actual node_modules version of the library. In the latest versions, there is a CLI command that doesn’t exist in version 13.

```
ng cache clean

rimraf .\.angular\
```

![Updated version of the Angular library](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8evxw1u6cy3kkaijg4dx.png)

Of course this solution is far from excellent, but at least it works. The alternative would be to deactivate the cache on the build of the application (we don’t care about the build of the library, but **since we are in a single workspace, no cache will be used at all**). We will try with a fourth version of the library and the following configuration :
```
ng cache disable
```

![Angular cache disabled](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x16rep2bcnzaz4dmcy65.png)

Then we can rebuild the application anytime we want and whatever the version of the library, we will have the proper version. Of course it’s not a perfect solution because caching would improve our build time, but it’s good to know that even if the hash of the library is ok, even if the local source code is ok, well you really can’t know what version is actually stored in the cache, because if we look into the cache, we can see that the code is already precompiled by Angular :
```
ng-lib\.angular\cache\13.3.11\babel-webpack (for example)
```

![Angular precompiled cache](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1bz4cc3w9opa4sxl17v1.png)

## Conclusion
This local npm registry Verdaccio is really nice to test your Angular library publish skills and parameters. In many cases we don’t really care about the actual version of our libraries other than compatibility, but sometimes, well things happen.

### Source code
Source code for this article can be found here [angular ng-lib](https://github.com/aboudard/ng-lib)