Using NuGet in Sitecore Solutions
Recently I spoke in Berlin at SUGCON 2018, the 5th anniversary of this amazing conference —made by and for the Community. During my talk I highlighted one of our customer’s solutions regarding DevOps, using VSTS and following the HELIX guidelines. One of the key elements there, I’d like to expand on today: the usage of NuGet in Sitecore solutions.
I believe that everyone will agree that when seeing the following 2 diagrams, a welcome similarity enters the mind that sparks ideas about how one could cross over to the other and vice-versa:
The first is the dependency structure desired from the HELIX documentation and presentations. The second is the NuGet dependency structure from the NuGet documentation over on the Microsoft Documentation website.
It felt like NuGet was the logical fit for packing the HELIX modules in our solutions, which had matured into reusable components.
HELIX and the maturing of Modules
I need to issue a fair warning here, just as I did in Berlin: HELIX is not for reusability. Do not fall into the trap of trying to build only generic reusable components. It is not possible to do so and for small to medium customers it’ll never even be required. SXA are Sitecore’s reusable components and if you find that something is missing that’s so generic that you use it with every customer, I highly encourage you to submit the idea to Sitecore. Chances are it’s already on their backlog and you can vouch for it by bringing it forward, or cooperate on its creation.
With large customers we get the opportunity however, to look at reusability as a positive side effect of using the HELIX architecture when creating our solutions. The approach I advise Architects to follow, is:
- Only use established modules already in your NuGet at project start
- Do not plan the creation of any module in your project, it’s not the project’s goal to deliver modules
- Do a regular cross-solution architect meeting and keep an overview of all Foundation and Feature level modules designed and implemented in all solutions
- When a Foundation or Feature level module has been left unchanged for at least a duration of 3-4 months and is functioning properly validate if this functionality is viable for NuGet availability
- Port any qualifying module to NuGet
If all is well then any reason for change should be a cross-solution requirement (otherwise your module is too project specific or has a bloated functionality scope). Keep in mind the package cohesion principles, as they form the basis of HELIX and are very much applicable when using NuGet packages.
The meat on the bone: How to create a package?
Creating NuGet packages is straight forward and relatively easy, besides being very well documented and subjected to an ample supply of tutorials. I won’t go into full details here, especially when it comes to modules that do not include any Sitecore Items. Here’s a simplified view of what a solution might look like for a NuGet packaged module:
So where the Web project packaging follows standard NuGet documentation, the packaging of the TDS project does not. For TDS however, there is very good NuGet support, allowing you to package your items into NuGet and retrieve them using very much the same way that one would use for regular NuGet projects. In the properties of a TDS project, one can find the following tab:
There’s 2 important parts:
- There needs to be a path to Nuget.exe. Which is easiest to establish when including a dependency on the NuGet.CommandLine package in NuGet. This will ensure it is available during build, regardless of the install on the build machine itself.
- As for metadata —like the .nuspec file for the normal NuGet packaging of a project— the TDS properties tab, includes all the same fields (and must be filled accordingly). You may even include dependencies, in case you have item packages of a Feature that relies on a Foundation level package to be present.
TDS, ok. But what about Unicorn?
First a disclaimer: I haven’t used this approach on a project that uses Unicorn yet, but theoretically there should be nothing stopping you from following this approach.
So Unicorn is different, because generally people don’t create a project that enables viewing the serialized files in the solution (since there’s no real need). As long as the files are in a source-controlled space, they will be picked up and distributed. The configuration files are situated in their respective Web Application Projects and are edited, viewed and deployed from there. While you can of course pull NuGet packages anywhere, I propose the creation of a Web Application Project specifically for pulling in Unicorn NuGet packages. Besides giving an easy NuGet UI accessibility point, this also enables us to easily include the pulled configurations into our deployment, using your familiar preferred way.
To create a Unicorn NuGet package, one simply needs a good .nuspec file that includes the desired YML hierarchy and the corresponding Unicorn configuration.
To install a Unicorn NuGet package, open the Manage packages UI for the project or use the NuGet Package Manager Console, to pull the package into the project.
If anyone has used this approach or any other approach, please leave your take on it in the comments. I’d love to hear about your experience with this.
NuGet is an awesome way of packaging your Foundation and Feature level modules for reuse, in case they adhere to proper scrutiny and healthy common sense (think KISS). Packaging modules is easy (read the documentation) and both TDS and Unicorn can be packaged to include Sitecore Items in your NuGet packages.