


A standard way for building client-side SharePoint solutions


Bundling by default


Why bundling external frameworks in SharePoint Framework is a bad idea

To illustrate why bundling external JavaScript frameworks in SharePoint Framework let's build a simple Web Part using Angular and styled using ngOfficeUIFabric.

Let's start by creating the Web Part. Since the SharePoint Framework Yeoman generator doesn't support scaffolding Angular Web Parts, we will use the 'no JavaScript framework' Web Part and add Angular to it ourselves.

The 'no JavaScript framework' option selected in the SharePoint Framework Yeoman generator

Next, let's install Angular and ngOfficeUIFabric into our project by running in the command line:



$ tsd install angular --save

Finally, let's reference both frameworks in our Web Part:

import {

import styles from './HelloWorld.module.scss';
import * as strings from 'helloWorldStrings';
import { IHelloWorldWebPartProps } from './IHelloWorldWebPartProps';

import * as angular from 'angular';
import 'ng-office-ui-fabric';

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {

  public constructor(context: IWebPartContext) {

  public render(): void {
    this.domElement.innerHTML = `
      <div class="${styles.helloWorld}">
        <!-- omitted for brevity -->

      angular.module('helloworld', []);

      angular.bootstrap(this.domElement, ['helloworld']);

  // omitted for brevity

At this point it doesn't really matter that the Angular code doesn't do anything. What matters is what we do next.

Let's do a release build of our Web Part by running:

$ gulp bundle --ship

If you now look into the ./temp/deploy folder you will see three files: your Web Part's manifest, the main bundle and a file with localization strings.

SharePoint Framework Client-Side Web Part release bundle files

Notice the size of the main bundle: 336KB.

Main Web Part bundle highlighted in Finder

If look into the contents of the generated bundle you can see that, next to your Web Part's code, it contains Angular (line 2) and ngOfficeUIFabric (line 12).

Now, let's add another Web Part to our project by calling:

$ yo @microsoft/sharepoint


Once again, let's execute a release build by running:

$ gulp bundle --ship


Two Web Part bundles highlighted in Finder

If you would add both Web Parts to a page, users would be essentially downloading Angular and ngOfficeUIFabric twice - once with each Web Part. What if you would consider this approach in the context of a complete intranet with many sites, pages and Web Parts? How inefficient would that be?

Luckily there is a better way to handle external frameworks when building Client-Side Web Parts on the SharePoint Framework, and it doesn't even require you to change anything about your code.

Keep external frameworks... external


In the previous example we saw how the SharePoint Framework bundles Angular and ngOfficeUIFabric together with our Web Part's code. When working with the SharePoint Framework we can however choose whether we want to have our dependencies bundled together with Web Parts or not.

In order to load external JavaScript frameworks from a URL instead of bundling them together with the Web Part, we have to specify them as an external module in the config/config.json file's externals section. When using Angular and ngOfficeUIFabric you would extend your configuration like this:

  "entries": [
  "externals": {
    "angular": {
      "path": "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js",
      "globalName": "angular"
    "ng-office-ui-fabric": "https://cdnjs.cloudflare.com/ajax/libs/ngOfficeUiFabric/0.12.3/ngOfficeUiFabric.js"
  "localizedResources": {

In the example above we specify that we want to load Angular and ngOfficeUIFabric from an external location. Please note how the names we used (angular and ng-office-ui-fabric) match the names we used in the import statements in our Web Parts.



In the exampe above we load our external JavaScript frameworks from CDN. Using a CDN isn't required though and you might as well use a hosting location owned by your organization or even a SharePoint Library. As long as users can access the scripts when working with Web Parts everything will work as expected.

Having extended our project configuration with the hosting locations for Angular and ngOfficeUIFabric, let's clean up previous builds and once again run a production build using:

$ gulp nuke
$ gulp bundle --ship


Two Web Part bundles highlighted in Finder

Our Web Parts still need Angular and ngOfficeUIFabric though, so it wouldn't be fair to say that we just saved 330KB on each Web Part. In the current setup however, both Angular and ngOfficeUIFabric will be downloaded once for all Web Parts when the user visits the page:

SharePoint Workbench opened with Chrome Developer Tools showing network stats for the current request


Angular and ngOfficeUIFabric entries highlighted in the Chrome Developer Tools network stats


So what's the point of bundling?


Despite its impact on bandwidth, bundling external frameworks with SharePoint Framework Web Parts makes sense in some scenarios. For example, if your organization has a standard solution, that should work on any intranet and you can't rely on which frameworks are already available on the page, bundling is an easy way for you to ensure that everything that's required for your Web Part to work as expected is available. Some organizations don't allow loading scripts from public CDNs and providing them together with your Web Part is one way to work around that limitation. Also, if your Web Part requires a number of smaller scripts, it's better from the performance point of view to combine them together into a single bundle than to load the different script files separately. If that collection of scripts is used by multiple Web Parts then it would make sense to store it separately and reference it as external script.




comments powered by Disqus