Loading Angular and ngOfficeUIFabric from CDN in SharePoint Framework

With the latest release of the SharePoint Framework you can load Angular and ngOfficeUIFabric from CDN in your Client-Side Web Parts. Here is how.

Angular for the masses

Angular is one of the most popular JavaScript frameworks for building client-side applications. Many developers love it for its modularity and separation of the different pieces of the application.

Despite the fact that the SharePoint Framework Yeoman generator doesn't offer support for scaffolding Angular-based Web Parts, there is a lot of demand for using Angular with the SharePoint Framework. And the great news is, that you can use Angular for building Client-Side Web Parts on the SharePoint Framework.

Sample SharePoint Framework Client-Side Web Part built using Angular

Angular Client-Side Web Parts with style

When customizing SharePoint, the more the customizations blend in with SharePoint, the more intuitive they are to use and the more they feel like a part of SharePoint. To help us make our customizations look like they belong to SharePoint, Microsoft built Office UI Fabric - an implementation of the Office-family design language.

Screenshot of the Office UI Fabric website

Office UI Fabric consists of styles, fonts and a set of components, familiar from other Office web applications - all of which we can use to style our Web Parts.

While using styles and fonts is pretty straightforward, using the Office UI Fabric components gets a bit more complicated. Initially the Office UI Fabric offered sample code to see how the components are supposed to work, but if you wanted to use them with a specific JavaScript framework, such as Angular, you had to implement the directives yourself. With the release of the SharePoint Framework Microsoft released a React implementation of the Office UI Fabric components, but if you're using Angular there's not much use of it to you.

Using ngOfficeUIFabric for building good-looking Angular Web Parts

A while back, fellow-MVP Andrew Connell started a community initiative called ngOfficeUIFabric, to implement Office UI Fabric components as Angular v1.x directives.

Screenshot ngOfficeUIFabric demo website

Currently ngOfficeUIFabric contains the most frequently used Office UI Fabric components implemented as ready-to-use directives. If you're building SharePoint Framework Client-Side Web Parts using Angular, I would strongly recommend you use ngOfficeUIFabric: it will clean up your code and help you focus on building your application rather than its plumbing.

ngOfficeUIFabric is an open-source initiative and if you have feedback or improvements please contribute them on GitHub.

ngOfficeUIFabric and SharePoint Framework - bundle it

If you've tried using ngOfficeUIFabric with the SharePoint Framework, you very likely stumbled upon the same thing as I did. It was impossible to load ngOfficeUIFabric from CDN and the only way to use it was to include both Angular and ngOfficeUIFabric in the Web Part's bundle. While it doesn't seem all that strange at first, what do you think would happen if you had four or five Web Parts on the page, all built using Angular and using ngOfficeUIFabric, all loading them from the particular Web Part's bundle?

The fact that ngOfficeUIFabric couldn't be downloaded from CDN in SharePoint Framework Client-Side Web Parts wasn't ngOfficeUIFabric's fault. ngOfficeUIFabric is implemented as an UMD module that just works. It was a bug in the SharePoint Framework, that forced us to bundle Angular and ngOfficeUIFabric with the Web Part.

This changed however. With the latest release of the SharePoint Framework (v0.2.0), we can now load Angular and ngOfficeUIFabric from CDN. Here is how.

Loading Angular and ngOfficeUIFabric from CDN in SharePoint Framework Client-Side Web Parts

Specifying the URLs to load Angular and ngOfficeUIFabric from

The first thing that you need to do, to use Angular and ngOfficeUIFabric from CDN in the SharePoint Framework, is to specify the URLs from which both frameworks should be downloaded. This is done in the config/config.json file's externals section:

{
  "entries": [
    // omitted for brevity
  ],
  "externals": {
    // omitted for brevity
    "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": {
    // omitted for brevity
  }
}

First, we specify the URL for Angular. Because Angular is not an AMD-module, we have to use the extended notation where we specify the URL using the path property and the name of the global variable with which Angular will be registered using the globalName property.

Next, we add an entry for ngOfficeUIFabric. Because ngOfficeUIFabric is a UMD module, it's sufficient to just specify the URL from which the SharePoint Framework should download it.

Although ngOfficeUIFabric depends on Angular, we don't need to specify any dependencies in the configuration. ngOfficeUIFabric's UMD definition specifies itself that it depends on Angular and it will ensure that Angular is loaded before proceeding with loading itself.

Adding Angular typings for TypeScript

The next thing we need, to properly use Angular in our Client-Side Web Part, are TypeScript typings for Angular. We install them using the following command:

tsd install angular --save  

This command downloads the Angular typings for TypeScript from the Internet, adds them to the typings folder and saves the reference in the tsd.json file in case you need to restore typings for your project.

Using Angular and ngOfficeUIFabric in a SharePoint Framework Client-Side Web Part

With everything in place, the last thing left to do is to reference Angular in the Web Part.

import {  
  BaseClientSideWebPart,
  IPropertyPaneSettings,
  IWebPartContext,
  PropertyPaneTextField
} from [email protected]/sp-client-preview';

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

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

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {

  public constructor(context: IWebPartContext) {
    super(context);
  }

  public render(): void {
    if (this.renderedOnce === false) {
      this.domElement.innerHTML = `
      <div class="${styles.helloWorld}" ng-controller="HelloWorld as vm">
        <uif-button uif-type="primary" ng-click="welcome()">Click me</uif-button>
      </div>`;

      angular.module('helloWorld', [
        'officeuifabric.core',
        'officeuifabric.components'
      ])
        .controller('HelloWorld', ($scope: ng.IScope, $window: ng.IWindowService): void => {
          ($scope as any).welcome = (): void => {
            $window.alert('Hello world');
          };
        });

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

  // omitted for brevity
}

Alert message displayed by a sample Client-Side Web Part built using Angular styled with ngOfficeUIFabric

The sample above oversimplifies using Angular with ngOfficeUIFabric in the SharePoint Framework and it's merely proving that everything is working as expected. If you're looking for a real-life example of using Angular and ngOfficeUIFabric, I suggest you take a look at the sample To do application I have built and which I upgraded to SharePoint Framework v0.2.0 with loading Angular and ngOfficeUIFabric from CDN.

Sample SharePoint Framework Client-Side Web Part built using Angular

Summary

Angular is one of the most popular JavaScript frameworks for building client-side applications. Many developers love it for its modularity and separation of the different pieces of the application. With the latest release of the SharePoint Framework you can load Angular and ngOfficeUIFabric from CDN in your Client-Side Web Parts. This can help you improve the performance of your modern pages using multiple Web Parts.

Comments

comments powered by Disqus