Export Angular components as Custom Elements with “Angular Elements”
Disclaimer : the main subject of this post, Angular Elements project, is an alpha project, and APIs explained here could have changed since the release of this blog post. I will try to keep it up-to-date.
Update 20171217 : github repository demo has been updated to Angular 5.1.1, and AOT generation has been added. Final bundle is now around 200 ko with gzip compression. Thanks Boyan Barakov for the PR.
If you have heard the last news in the Angular community, the first major news was the release of Angular 5.0, see the blog post from Stephen Fluin for more details : https://blog.angular.io/version-5-0-0-of-angular-now-available-37e414935ced
One month ago, the Angular team announced at the Angular Mix conference in Orlando a new idea : Angular Labs. The idea is to communicate with the community about internal projects and get feedback more quickly.
There were 4 Angular labs projects announced : Schematics, Component Dev Kit, ABC, and the last Angular Elements. You can find more informations about the three first projects here : https://blog.angular.io/the-angular-team-at-angularmix-2d56fd7fde65
I will focus on the last one which is for me a big deal for Angular developers.
We all knew web components since their first announcement in 2011 by Alex Russell during Fronteers conference.
This standard that is supported by more and more browser natively, or with flags and polyfills is split into 4 specifications :
- HTML templates
- Shadow DOM
- HTML imports
- custom elements
Have a look at the official website for more informations about these 4 specs : https://www.webcomponents.org/specs
The last one is the most interesting for us.
Since the beginning of Angular, the goal was to follow the philosophy behinds these standards. Using one web component inside an Angular application is not a problem. This talk from I/O 2017 with Rob Dodson and Stephen Fluin explain it very well.
Sometimes, Angular developers share very powerful UI libraries as Angular libraries, but they are all linked deeply with Angular, and opening them to other technologies is a bit complicated.
Sharing just one or a set of Angular components to the outside world was not supported until now, and Angular Elements project will help us a lot in that situation.
I will quote Rob Wormald Angular Connect talk for his clean marketing sentence about them :
Angular elements are Angular components packaged as Custom elements.
With that in mind, you understand that it will create a bridge between your Angular component and the outside world, and use it outside an Angular application.
The main features of Angular Elements are :
- self-bootstrapping, just paste it in your page and it works !
- hosts an Angular Component inside a Custom Element
- bridge between DOM APIs and Angular Components APIs : @Inputs for properties, @Outputs for events, @HostBinding/Listener for observed attributes.
How to create an Angular Element ?
- Simply create a normal Angular component with inputs and outputs.
2. Include it inside a simple module.
This simple module has just referencing HelloComponent, and we add it also inside entryComponents metadatas. As a reminder, an entry Component is a component that Angular loads imperatively by type, in combination with ngDoBootstrap function. (https://angular.io/guide/ngmodule-faq#what-is-an-entry-component)
3. Register the component using the @angular/elements APIs.
4. Build it.
For this last part, i will simply use Webpack & Angular Compiler Plugin from @ngtools/webpack.
Have a look at this article for more details : https://www.ag-grid.com/ag-grid-webpack-ngtools/
5. Use it inside a simple html page.
Here we are using the element inside our page, and writing some vanilla js code to play with it. I just change the name attribute, and listen to events coming from the element.
6. Watch the result
We can see that the Angular element registered as a custom element is available inside window.customElements global registry (https://www.w3.org/TR/custom-elements/#custom-elements-api).
You can find all these files inside this github repository : https://github.com/vogloblinsky/angular-elements-demo
How it works ?
If you have a look at the source code of @angular/elements, the function registerAsCustomElements used above starts by calling the bootstrapping code, and after register the components.
As expected, the NgElement class used to register all the components as custom elements extends HTMLElement class like a vanillajs custom element should do.
What’s next ?
I will post an advanced article in the next weeks about more advanced feedbacks about this project.
Meanwhile Pascal Precht ʕ•̫͡•ʔ had a great talk about this subject during NG-BE conference :
We are just at the beginning of this labs project. The APIs are very young and they could change (so don’t use them in production), but i’m very excited about the cool stuff which will come next months.
I recommend watching the branch labs/elements on github for having the latest news about this project, and also following Rob Wormald (https://twitter.com/robwormald) and George Kalpakas (https://twitter.com/gkalpakas) on Twitter.
Thanks Wassim Chegham for the review.
Angular Elements Angular Connect 2017 @robwormald Rob Wormalddocs.google.com