Thursday, July 27, 2017

How to avoid breaking your SPFx project when dependencies change

Your SPFx project has a short list of dependencies.
They are listed in package.json

Thing is, these dependencies have a looong list of dependencies themselves, so that you end up with over 300MB folder of node_modules by the time you finish running npm install on a new SPFx project.

As most of you probably noticed, SPFx by default has a .gitignore file that excludes node_modules from ever going into your source control.

Which is a good thing - these packages are monitored and controlled by their authors and you don't need to manage all that code in your project, do you?

That means, whenever you move to a new computer or a new developer start working on a project, after cloning that project they must also run npm install before they can start working.

Now, npm install will start loading packages and dependencies as of TODAY, not as of when the project or the SPFx framework were compiled.

Some dependencies are specified by a version number, so no worries there (as long as the author did not re-publish new code with the same version number).

Others are specified as latest, or "*" or just with a major version - allowing minor versions updates. Since minor version updates suppose to be fully backward compatible and not contain breaking changes - sometimes that is not the case.

So, you go to your new PC, run npm install, and your project does not build.
You get a ton of errors, version mismatch, and have no clue why.

The reason would be probably a dependency you had was updated during that time (or god forbid - removed from npm!) which now breaks your project.

That is something I talked about during the first DevKitchen I attended, when I first saw SPFx. Having a huge list of dependencies I don't control, my project rely on, and that I don't have a copy of scared me.

And sure enough, since that day until today I had at least 4 episodes of dependency hell.

What can you do today

Without going into what Microsoft can and should do to avoid this in the future, here is what I plan to do and encourage you guys to do as well:

1. Build a test SPFx project, call it "Sanity"
2. Run npm install, and make sure the demo web part works by running gulp serve
3. Remove the .gitignore file
4. Store the entire huge project in your source control

Every so often, run npm update on this project.
Test if it is working - and if yes, commit the changes.

However, if your project fails to build, you know you got a breaking change. Do not commit, it will probably get fixed within a few hours.

Note that some breaking changes may come from a globally installed package, such as typescript.
So, it is a good practice to log these versions as well somewhere in your project. You can get that list by running "npm ls".

What to do if your project breaks

Now, once one of your project fails to build, look at where the errors are coming from.
It will probably tell you the packages and their dependencies.
Now, you can compare these packages with the ones you have in your "Sanity" project, and once you identify the ones causing the problem you can manually revert it by running:
npm uninstall {package}
npm install {package}@{last working version}

If you don't have that "Sanity" package, and do have a working version on a different computer - try to compare the versions between these two.

A quicker fix might be to simply copy the node_modules folder from the working project into your new broken projects.

It could be very frustrating spending valuable dev hours on maintenance instead of productive work, but hopefully these steps could help you cut down those hours.

No comments: