I'm starting to get into the angular 6 bits, and am very interested in Angular Elements as well as the new library projects. I have an upcoming project that will probably need both these new features.
I have the need to create custom UI components that are reusable across web frameworks, but I'd also like to have first class support for using them in angular projects. I've followed this tutorial and have an angular6 app that registers custom elements, and concats the webpack bundles in a single file. I can then use that single js file in a plain html page and everything works very well.
The sticking point is it would be great to create these custom elements in a library project. That way I can distribute my library on our internal npm registry, as well as build the js that contains all the custom elements and deploy it on a CDN.
Is it possible to build Angular Elements in the new library projects?
Introduction
What I will describe here is a way to have a mono-repo containing a main Angular app (host) and one or more Angular Elements based apps (childs). You will be able to use the elements in your main app by bundling all them together or you can pack your element with npm and import it as a npm dependency. This is heavily based on what is described by Manfred Steyer in his Angular Elements blog series so I advice you to read that to get some context and fill some missing pieces.
Be aware though, that currently the approach I describe here will not avoid duplicated dependencies across your multiple apps.
Solution
In your existing Angular project you can create a child application with ng generate application <name>
. See documentation for more details.
Turn your newly created project to an Angular Element.
To help you build your projects take a look at the Angular CLI extension ngx-build-plus
here. For my case I didn't apply most of the recipe described in the ngx-build-plus
docs as it is about sharing dependencies across projects which I will not detail here. All I needed was what follows.
The steps to build this architecture are roughly:
ng add ngx-build-plus
ng add ngx-build-plus --project <name>
"build:client-a": "ng build --prod --project client-a --single-bundle true --output-hashing none --vendor-chunk false"
ng build
, ng serve
angular.json
angular.json
. Each app has its own configuration and scripts entry.After you build your elements project, its single file bundle will typically go to ./dist/<project-name>/
. You can create an npm package from that content and use it as a library.
Notes
Two ways to bundle the child apps with the host app. In the host app scripts configuration, you either add the path to the child apps in the dist/
folder or you add the path to the child apps in node-modules/
folder (when child apps are imported as npm packages).
Creating an Angular library instead of an Angular application for this purpose will not work because Angular libraries generated by the CLI cannot be used outside an Angular project - this was not very clear in the documentation.
Make sure that the component doesn't have dependencies to the parent app and you should be fine. I handled dependencies by converting them to component inputs or by doing content projection.
When you have a component A which includes a component B. You want to turn component A into an angular element but component B is used in several parts of your application. If you don't want to maintain two copies, one in the application and other in your component A library, it might be a good case to take advantage of content projection (aka Web Component slots).
Be aware that I haven't done this in production and its not what you would call a stable architecture.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With