HowTo: Angular Elements in SharePoint Framework Projects - Two Projects

Wednesday, September 5, 2018 8:15 AM
Microsoft MVP Logo

In my last post, I talked about using Angular Elements in SharePoint Framework projects. That post showed how to do this using a single SharePoint Framework Project. In this post, I show you a much better option that uses two projects.

Using a single SharePoint Framework project to create a custom element using Angular Elements is not a good option. Not only can you not use the Angular CLI but the resulting payload was way too big to be a viable option.

The way I’d recommend you do it by using two projects:

  • Use the Angular CLI to create a custom element using Angular CLI
  • Create an SPFx project that imports the resulting bundle from the Angular CLI project

The advantage of this approach is it negates the two downsides to the single-project approach. This means not only can you use the Angular CLI to create your custom element with Angular Elements, but you can also use it to run, debug, test and upgrade your application.

The only downside to this approach is you now have two projects, a small trade-off.

Create the Custom Elements with Angular Elements

The first step is to create your custom element using the Angular CLI. I showed the relevant code in the first part of this series. Refer to that post or scroll to the end of this post to download the code.

Configure the Angular CLI Project

This step isn’t required but it will make your life easier. When the Angular CLI builds your project for production using AOT, it will generate four hashed JavaScript files. I like to add an extra step to the build process to concatenate all four of these files into a single bundle and add it to the SPFx project.

Assuming the following:

  • My Angular CLI project is named ngElementsHelloWorld
  • My SPFx project is named ngElementsHelloWorldSPFx
  • The two projects are living side by side

I added the following NPM script to my Angular CLI project’s package.json file:

"spfx-build": "ng build ngElementsHelloWorld --prod --output-hashing=none && cat dist/ngElementsHelloWorld/{runtime,polyfills,scripts,main}.js > ../ngElementsHelloWorldSPFx/src/webparts/helloWorld/app/ngElementsHelloWorld.js"

Now, when I run npm run spfx-build, the Angular CLI will build the project with AOT. I’ve told it to not add the hash to the filenames as it will be hard to work with these files in the remainder of the script.

The script then concatenates all four files runtime.js, polyfills.js, scripts.js and main.js into a single file ngElementsHelloWorld.js into the ./src/webparts/helloWorld/app/ folder within my SPFx project.

Use the Custom Element Bundle in an SPFx Web Part

Now for the fun part… let’s get this working in a SharePoint Framework project.

The first step is to add a NPM packages used to act as an additional polyfill to fix browsers who don’t yet natively support custom elements and shadow DOM:

yarn add @webcomponents/custom-elements/src/native-shim @webcomponents/webcomponentsjs/bundles/webcomponents-sd-ce

Now, update your web part to import the polyfill, the custom element and use it in your web part:

Test & Enjoy Manageable Payloads!

Let’s see this work. First, build the Angular project using the custom script we created:

npm run spfx-build

Now run your SharePoint Framework project:

gulp serve

Add your web part to the page to see it work in the local workbench:

We eliminated the “can’t use the Angular CLI” downside of the previous “one-project” approach, but did we eliminate the payload issue too? You bet… check this out!


That’s a 90% reduction from the “one-project” approach. If you deploy this to production, the Office 365 CDN or your CDN of choice will gzip the file down to 328kB (125kB gzipped). That’s a perfectly acceptable sized web part. Success!

But Wait… It’s Going to Get Better!

Can it get even better? Yup!

Angular v7, due out in September / October… just a month or so after this post has been published… will include a brand new rendering engine.

This new rendering engine, named Ivy, was built from the ground up with speed & tree-shaking in mind. While we haven’t seen the final results, not only is the rendering blazing fast, but it’s resulting in payloads around 3kB gzippedd for typical Angular Hello World projects. What will the final size of an SPFx bundle be? We’ll see when Ivy ships!

Your existing projects likely won’t have to be touched other than updating the package dependencies. Just run the Angular CLI project upgrade process that will update the packages, rebuild & redeploy everything.

But if you did the “one-project” approach, you wouldn’t be able to benefit from this because, as I explained in the second post in this series, no AOT for you!

My Opinion: Two Projects is a Good & the Only Approach

The evidence speaks for itself… having two projects to deal with is not a big deal or a slight to your productivity. Most of us are using VSCode as our editor and having two instances open, one with each project loaded, is not a big deal in any way.

Because of this, I recommend using the two-project approach. You get the benefit of using the Angular CLI as well as a manageable resulting bundle that you can deliver to your customers.

comments powered by Disqus