Loading frameworks and libraries in SharePoint Framework projects


There are a number of ways to reference frameworks and libraries in SharePoint Framework projects. But which one is the best for your project?

A standardized model for SharePoint customizations

SharePoint Framework is a new model for building SharePoint customizations. Based on JavaScript it standardizes how developers build client-side customizations for SharePoint. In the past you would have to add your scripts to the page and attach them to arbitrary elements on the page. With the SharePoint Framework you get a supported API to integrate your customization with SharePoint in a future-proof way.

There is a library for that

Building client-side solutions is popular not only in SharePoint. Over the last few years hundreds of client-side libraries have been published on the Internet. Using these libraries developers can quickly build rich and powerful solutions that do virtually anything ranging from showing latest tweets to allowing data entry and visualization.

Using libraries significantly shortens the time required to build a solution, but it comes with a price. If used incorrectly, libraries will expand the size of your customization, slowing down loading of the page and eventually leading to a poor user experience. Luckily, SharePoint Framework offers you a number of ways to reference other frameworks and libraries.

Reference frameworks and libraries in SharePoint Framework projects

SharePoint Framework provides you with a number of ways to reference frameworks and libraries in your project. Each approach has its pros and cons which you should understand before making your choice. Whichever approach you choose, keep in mind that it applies to the whole project, rather than to a specific web part.

Include the library in the web part bundle

One way to reference a JavaScript library in a SharePoint Framework project is to install it as a package using npm and then import the library in the web part.

Taking Angular as an example, you would first install it in your project:

$ npm install angular --save

Next, you would install its TypeScript typings:

$ npm install @types/angular --save

Finally, in your web part you would import angular:

import * as angular from 'angular'

This is all you have to do. Next time you build your project, SharePoint Framework will automatically include Angular in the bundle generated for your web part. But here’s the catch: have a look at the size of the generated bundle.

Web part bundle file highlighted in macOS finder

The optimized version of the bundle generated for a web part, that doesn’t do much more than saying ‘hello’, is 174KB. If you would put two different web parts built this way on one page then you would end up downloading Angular twice: once with each web part.

While loading a library into the web part bundle is the easiest way of referencing a library in SharePoint Framework client-side web parts, it’s also one with the highest performance cost. It’s okay for you to use it for tests and experiments but beyond that I would strongly recommend you not to use it and consider one of the other options instead.

Load the library from a URL

When building client-side solutions, developers often choose to load frameworks and libraries from CDN. By doing this, they don’t need to worry about deploying the libraries together with the solution. Additionally, if they choose just the right CDN, they could improve the performance of their solution a lot. If users have a copy of the particular framework in their local browser cache, then the solution will reuse that copy instead of downloading it from the Internet, which will make the page load faster.

SharePoint Framework supports loading frameworks and libraries from URLs without any change to code, which is a great way to see the benefit of using this approach over including it in the bundle.

To load a library from the URL, all you have to do is to register it as an external resource in the config.json file. There is one thing you have to keep in mind: how you register your library depends on its format. If the script is distributed as a module, you only need to specify the URL. If it’s not a module, then you also have to specify the globally known script name and optional dependencies.

Taking Angular as an example, Angular is not a module so you would load it from CDN by adding to config.json:

{
  "externals": {
    "angular": {
      "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
      "globalName": "angular"
    }
  }
}

In comparison, if you wanted to use ngOfficeUIFabric - Angular directives for Office UI Fabric, which are distributed as a UMD module, then you would register it using:

{
  "externals": {
    "ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.12.9/ngOfficeUiFabric.min.js"
  }
}

If you look at the generated bundle after configuring Angular to be loaded from CDN, you will see a significant improvement: the file is merely 6KB.

Web part bundle file highlighted in macOS finder

It wouldn’t be quite correct to say that you have just optimized 170KB away. When users navigate to a page with web part on it using Angular, SharePoint Framework will still try to load Angular, either from the local browser cache or from the specified URL.

Loading libraries and frameworks from CDN is a great approach that you should consider to improve the performance of your solution. Some organizations use a private repository of popular frameworks which allows them to ensure their integrity. The URL, that you are using when registering a library as an external resource in your SharePoint Framework project, does not need to be pointing to a CDN. In fact any location is acceptable as long as users working with your web part can access that URL.

Deploy your own copy of the library

Another way to reference a library in your SharePoint Framework project is a combination of both approaches described previously. You install the library as a package using npm, but then define it as an external resource with a path pointing to the node_modules folder.

Taking once again Angular as an example you start by installing Angular and its TypeScript typings:

$ npm install angular @types/angular --save

Then, in the config.json file you add an entry to the externals section:

"angular": {
  "path": "node_modules/angular/angular.min.js",
  "globalName": "angular"
}

Similarly, as when loading Angular from CDN, you still have to take into account the format of the library and format the entry in the externals section accordingly.

When debugging the project in the SharePoint workbench, SharePoint Framework will load Angular from the node_modules folder. When you however generate a release build of your project, SharePoint Framework will copy Angular to the dist folder as a separate file.

Angular highlighted in the dist folder after building a SharePoint Framework project

One important thing to keep in mind is that SharePoint Framework will not minify the library referenced as external so the URL you use in the externals section should point to its minified version.

If you have multiple web parts in your project using Angular, then all of them will reference the same Angular file which will be downloaded by users only once and stored in their local browser cache for subsequent requests.

Although as not efficient as loading a library from a CDN, this approach is perfect when you have a standard solution that you deploy to different tenants, you cannot rely on CDNs (some organizations block them for security reasons) and you don’t want to host copies of the framework yourself. Because each solution is deployed with all its resources, you don’t need to worry that upgrading one solution will affect another and you don’t need to maintain a list of libraries and frameworks and their versions that you use across all your solutions.

Summary

SharePoint Framework offers a number of ways to reference frameworks and libraries in your project. Each approach has its pros and cons which you should understand before making your choice. Whichever approach you choose, keep in mind that it applies to the whole project, rather than to a specific web part.

Others found also helpful: