Yesterday, I was running yet another Angular workshop. After explaining how to install dependencies using npm, I show how to use Yarn (see this blog), a faster alternative to npm, and suggest that the students should consider using Yarn.
Before the workshop, I give handouts with several projects to the group and then ask the group to open a particular project, install the dependencies and run the app. Usually, everything goes smoothly, but this time many people started to complain about a runtime error. In this app, I was using themes from Angular Material 2, but the app couldn’t find the file “node_modules/@angular/material/core/theming/prebuilt/indigo-pink.css”.
I was strange. I tested all the projects two days before the class. After checking the content of the node_modules directory on Paul’s computer, I couldn’t find even the directory node_modules/@angular/material/core let alone that CSS file.
Then I asked if everyone gets this error? Everyone except Jim got this error. Jim was using Yarn for installing dependencies while everyone else was using npm. After learning this, I guessed what was the problem.
I’ using Yarn too, and all my projects included the file yarn.lock, which is created after the initial install storing all packages and their versions there were installed for the project. When you do the yarn install next time, it checks if the file yarn.lock is present, it installs exactly packages of those versions that were listed in yarn.lock. This file can be checked into the version control repo used by your team to ensure that everyone would have exactly the same dependencies.
Now let me explain what happened in the classroom. The package.json in that project included the dependency
The file yarn.lock in that project had the following:
"@angular/material@^2.0.0-beta.2": version "2.0.0-beta.2" resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.2.tgz#65ee8733990347b7518b7f42113e02e069dc109b"
Hence, when Jim ran his Yarn install, he got Angular Material 2 2.0.0-beta.2, which had the file “node_modules/@angular/material/core/theming/prebuilt/indigo-pink.css”
But last week, a new version (Beta.3) of Angular Material 2 has been released with a breaking change – they rearranged the file structure:
So the students who didn’t use Yarn, got the latest version while my project used “the old” location of that CSS file.
Fixing this issue in the app was an easy task, but I wanted you to appreciate that Yarn gives you predictability in the projects that have multiple dependencies. Some library author introduces a breaking change, and your app gives a runtime error.
After fixing the CSS location in the app, I deleted my yarn.lock file and re-ran the install. The newly created yarn.lock has this fragment:
"@angular/material@^2.0.0-beta.2": version "2.0.0-beta.3" resolved "https://registry.yarnpkg.com/@angular/material/-/material-2.0.0-beta.3.tgz#ec31dee61d7300ece28fee476852db236ded1e13"
The first line indicates the dependency as it was listed in my package.json, and the second line shows the actual version that has been installed. Now my project is working again… until the next breaking change.
Update. Here’s another situation I ran into that would prove the usefulness of yarn.lock.