I recently updated this blog to a new version of Gatsby. When I did, I encountered an issue: when I tried to build the site I got an error about Sharp not being installed correctly.

Something went wrong installing the “sharp” module

The specified procedure could not be found. ?\D:\git\personal-blog\nodemodules\gatsby-plugin-manifest\nodemodules\sharp\build\Release\sharp.node

Removing the directory and reinstalling didn’t reveal any errors. When I did a Google search for the error, I followed a few links and found this:

This means that there are multiple incompatible versions of the sharp package installed in node_modules.

To fix this, you’ll need to update all Gatsby plugins in the current project that depend on the sharp package.

It then suggests that you can use npm list sharp (or yarn why sharp) to determine which packages are requesting which versions of sharp.

I noticed that favicons depended on sharp ^0.22.1. The ^ symbol usually allows minor version updates but not major version updates, but for packages still on major version 0 it only allows patch updates. This meant it was incompatible with the ^0.23.1 required by Gatsby’s official plugins. This doesn’t cause an issue during the install process, as NPM simply installs both 0.23.1 and 0.21.1, allowing each dependency to use their own version of sharp. But sharp (for some reason) doesn’t support having multiple versions installed within a project, so we get the error.

In favicons 5.5.0 the dependency has been updated to ^0.23.1. So we can just update favicons, right? Well, not quite. favicons is required by favicons-webpack-plugin which specifically requires favicons@5.4.1. So we’d need to submit a PR to this project asking them to update their dependency to the latest version of favicons and wait for them to publish the update. And even then gatsby-plugin-favicon for some reason specifies an exact Git commit of favicons-webpack-plugin to use, so we’d need to submit a PR to that project too, then wait for them to release the update. I want my blog to work now, I don’t want to have to jump through all these hoops and wait for other people!

An obvious answer is just to remove gatsby-plugin-favicon and find another way to include favicons, but this then means I have to go through the selection process all over again and configure a new plugin. Things were working before, why can’t they keep working beyond a Gatsby update? Can’t I just force everything to use v0.23.1 of sharp? The answer is no, at least not with NPM.

Enter Yarn

While it’s impossible to work around this issue with NPM, Yarn allows it. It’s as simple as adding the following to package.json:

"resolutions": {
    "sharp": "^0.23.1"
}

Now every dependency that uses sharp will be forced to use the same version of it.

Switching to Yarn

Yarn is very similar to NPM, but the commands are structured a little bit differently. In order to make the switch easier, here are the commands my build environment previously used for NPM and their Yarn equivalents:

npm install -g gatsby
npm ci --production
npm run-script build
npm run-script deploy
yarn global add gatsby
yarn install --frozen-lockfile --production
yarn run build
yarn run deploy

Conclusion

After adding the resolutions field and running yarn install my blog builds successfully once more. Yarn basically does everything NPM does, but has additional features and flexibility that are extremely helpful for resolving issues like this one. Now that Yarn is supported on AWS CodeBuild I have no reason to use npm any more.