Gosh Yarn It
What is yarn?
While Yarn is designed completely replace the npm workflow, it works in concert with the existing package.json: adding or removing packages with Yarn will update both the package.json and yarn.lock.
The main commands you’ll need:
1 2 3 4
Why bother to switch from tried-and-true npm?
Locking down the right versions of all your dependencies can be tricky.
For example: I accidentally upgraded react-addons-test-utils to a new version by adding it directly with
yarn add react-addons-test-utils. This got the latest version of the package, which meant it no longer had the same version number as react and react-dom – we had specifically pinned those at an earlier minor version.
When I ran the tests, this error popped up:
Module not found: Error: Cannot resolve module 'react-dom/lib/ReactTestUtils' in /Users/ebookstein/newrelic/browser/overview-page/node_modules/react-addons-test-utils (module was moved between versions of react-dom)
To pin react-addons-test-utils at a specific version, I added the version to the package name like this:
yarn add firstname.lastname@example.org.
Of course, locking down dependencies at the right version numbers is something that npm did for us as well. Why replace it?
There are some minor benefits that came across right away from using yarn instead of npm. For one thing, I no longer have to remember
--save – think of all the time you’ll save not pushing branches up to Github only to have your tests fail!
But there are some big-picture benefits too. We were using npm shrinkwrap to stabilize versions and dependencies. But shrinkwrap easily gets out of sync with package.json if you forget to run
npm shrinkwrap, and when it fails, it fails silently.
If you want the full-length list of big-picture reasons that Facebook came up with, check out their blog post about yarn.
Switching to yarn: a few tricky bits
Installing yarn itself is easy.
brew install yarn
Then go to your project directory and run
yarn to install all the packages and generate a yarn.lock (similar to Bundler’s Gemfile.lock for Ruby).
Migrating from npm to yarn is not totally seamless, however. For some reason, a few packages don’t transition as easily. In particular I had issues with node-sass and phantom-js. In one case, the issue was resolved by specifically adding the module with yarn (
yarn add node-sass). In the case of
phantom-js, though, we had to add a post-install script to our package.json that would run a phantomjs install script.
Also, if you use Jenkins or other tools that keep a saved copy of your node_modules, you might have to clear out the old node_modules and reinstall.
For Jenkins specifically, try:
- clearing the workspace,
- killing the instance of Jenkins, or
- add a post-build step to delete the workspace every time (which therefore runs a complete installation every time)
Fun fact: yarn preserves many helpful features of npm, like symlinking.
For example, if you wanted to use your personal copy of react instead of Facebook’s react (pretend!), then you could run
yarn link inside of the react directory, then
yarn link react in your project directory. This would then substitute a link to your personal react copy for every
Tying up loose ends
So far, it’s been fun to knit yarn into our development process! Though I’m still working through some of the knots…