SharePoint – Selective Deployment of NuGet packages via a module

The best practice for deploying files from a SharePoint project is to create a Module and to include inside the different files to deploy on your SharePoint site. This is easy, clean and efficient and we can chose where exactly will be our files, like in a folder with our project/module name, in the Style Library.

But, today, I asked myself : “How can I deploy a JS library that is downloaded and maintained by the NuGet Packages Manager? And how to reference these files in, say, a WebPart?” I thought that I could simply reference the relative path to these files in the “Elements.xml” file of my module but, spoiler, it doesn’t work at all.

Some searches on Google suggested me some things like using mapped folder, just copy/paste the needed files, use a CDN, … Nothing that suited what I wanted.

So I started to think, to test, to experiment… And I finally found something clean, satisfying and, I hope, durable. This is what I’m going to explain in this post. We will start from an empty SharePoint project, this will avoid the most mistakes and confusion that we can get with an already existing solution.

The method

As the modules are perfect for deploying our files, we’re going to use one. We will trick NuGet and call this module “Scripts” thus the created folder will also be named “Scripts” and NuGet will download the files there, without worrying if it’s a common folder or something else.

A bit of context: I’m using a dedicated VM for development with Visual Studio 2015 and SharePoint 2016. So, first, we’re going to create a new empty SharePoint project with a name that shows it’s only for testing.

This will ask the targeted site collection and the security level. I chosed “Deploy as farm solution”.

Our project is now created, we start by adding our module that will contains the scripts files. Right click on the project à Add Item à SharePoint Module. This is really mandatory to call this module “Scripts” as this will be the folder name.

The Features folder and the Feature1 feature are immediately created too. The features tell to Visual Studio what files to deploy, what features to activate, …

Now that we have created our module, we’re going to download our first library, say jQuery, via NuGet. So… Right click on the project, “Manage NuGet Packages” and then download the latest “jQuery” version from there. When the installation is completed, we can see that our “Scripts” modules has received some new files (the jQuery library obviously).

The files selection

When new files are added to a module, they are also added to the “Elements.xml” file. This one gives the way to deploy the module files by telling their : local path, target path and if we’re going to add the files on the server or just keep them in the RAM. Our Elements.xml file now contains the following:

We don’t need the highlighted lines so delete them, we’re only going to keep “jquery-3.2.1.js” (it’s only for testing purposes anyway). Then, and because I want a clean deployment, we target the “Style Library” where we will create a dedicated folder (so we’re not going to accidentally delete some files from another project/module/whatever…). To do the following we:

  • Edit the Module tag by adding an “Url” parameters with “Style Library” as a value
  • Change the “Url” attribute of the “File” tag of jQuery by replacing “Scripts/” with “TestAssets/js”
  • Add to this same tag the “Type” attribute with the value “GhostableInLibrary”

To know what exactly do « GhostableInLibrary », check this:

That will give this result:

If we deploy the project and we go in the “Style Library” (http://<your site>/Style Library), we can see that we have a new “TestAssets” folder, containing a “js” folder, containing our jquery Javascript file:

Note: if the file hasn’t be deployed

It happens. When we deploy our project, we’re deploying a package created by the Features. Our module is referenced in the Feature1 feature and, sometimes, this feature is desynchronized with the current module state. To fix this issue, simply open the Feature1 and press CTRL+S to save it again and for the synchronization.

Module maintenance

“But, what’s going to happen if we add another library?” was the first question that came in my mind. Well, we’re going to discover that together… We have jQuery, why don’t we also take Bootstrap ?

When the installation is finished, we can see that the module’s Elements.xml file has been updated…

We can conclude 2 things: the previously removed lines didn’t reappeared (yay!) and the new Bootstrap files have been added.

We now just have to keep the first bootstrap file (so we only deploy the minified file), change the Url attribute and add the Type attribute with the value ”GhostableInLibrary”. If we deploy our project again…

Perfect. That’s exactly what we wanted.

But, Bootstrap has also added some CSS, in another folder?!

Oops. I absolutely didn’t take Bootstrap to show this possible case, I promise 😉

Bootstrap has indeed created a new folder called « Content » with about 10 new files. We of course need them to get Bootstrap working correctly and, consequently, we’re going to create a new module and include all these files inside with the goal to deploy it in the Style Library too.

The simplest way to do it is the following:

  • Rename the existing « Content » folder to « ContentTMP » (thus we lost nothing)
  • Create a new module with the name « Content »
  • Move all the files from the « ContentTMP » folder to the « Content » module (that is really a folder actually)
  • Delete the « ContentTMP » folder
  • Edit the « Elements.xml » files of the « Content » module the same way we previously did with the « Scripts » module
  • Update the « Feature1 » feature by saving it

Voilà! We now have access to these CSS files. If another libraries from NuGet create another folders, you just have to repeat this procedure again for every new folder.

What if a package is removed with NuGet?

The referenced files will disappear from the Elements.xml file, that’s that simple.

Reference the deployed files

If you leave your cursor on one of the deployed files in the Style Library, you will see what is its absolute link. Like, for the minified bootstrap file:

We can also use relative links in, why not, a WebPart to import jQuery and Bootstrap. I hope this helped you as much as this helped me. And sorry if I made some English mistakes.

Related Posts Plugin



L'informatique est un monde magique et complexe, partager quelques connaissances et astuces au travers de ce blog me permet de participer à la construction d'un web meilleur pour tous !