Search code examples
dependency-managementclojurescriptpackage-lock.jsonshadow-cljs

What is the difference between using package-lock.json or shadow.cljs.build-report to track changes in dependencies?


I have been using Clojure, ClojureScript, lein, shadow-cljs, re-frame, reagent, Emacs, and CIDER to work on a Clojure/ClojureScript dynamic web app project.

Usually, I build the project by executing the command cider-jack-in-cljs in Emacs, choosing shadow-cljs, then shadow for REPL type, and, finally, app for the building option.

Currently, the project faces a reproducibility crisis. It is hard to know which dependencies are being changed on the project. In addition, every developer has their own local development environment. Things get even worse because this "mess" can even happen in a deployed environment since it depends on the machine that is doing the deployment (there is no CI/CD, deploys are manual).

It would be important to understand why/how/when/which dependencies were changed after every release.

There is an interesting command called shadow-cljs shadow.cljs.build-report (see documentation). It can be executed with npx shadow-cljs run shadow.cljs.build-report. This command builds a report showing the dependency tree as raw HTML.

One idea would be to keep the output of this command under version control and use git diffs to check the differences.

But, one co-worker said that package-lock.json already does that (see documentation). Hence, I started to wonder the differences between the two.

I can see at least one: the HTML file outputted by shadow.cljs.build-report renders nicely in a web browser, as a consequence, it feels better for human readbility.

Is there another difference? What are they?


Solution

  • Build Reports only report build information. It does list all the dependencies used with version but it does not lock them. Thereby it doesn't contribute to build reliability, it only serves as a control.

    You should keep the package-lock.json to version control. It is used by npm install to ensure that every time you run it all the same versions get installed. See the docs.

    Without the lockfile npm install will install packages in non-deterministic ways. Unfortunately most npm packages use version ranges to declare dependencies. So, without lock files you can never be sure which version you'll actually get.