vigie / clarity-webcomponent-starter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ClarityWebcomponentStarter

The purpose of this project is to serve as a starting point for Angular Clarity applications wishing to export components as Web Components using the new Angular Elements API.

The goal of the exported components is that they should be able to be used along side any number of other web components (that may or may not have used this starter) in a web app of any flavor using any tech stack.

Implementation

There are a few technical barriers in the way of acheiving the above goal that currently require work-arounds which will be explained in this section.

Firstly, Angular currently does not like to be loaded twice, so if you naively try to load two web components built using Angular Elements, you will run into this bug: angular/angular#23732

Secondly, the Angular library itself is currently not very tree shakable, leading to very large exported bundle sizes. Once ready, the new Angular Ivy compiler and renderer will solve this problem.

For now, to work around both of these issues we use the ngx-build-plus build tool to externalize the Angular library itself and also Angular's dependencies, making them the responsibility of the consuming app. Clearly, this results in web components that leak abstractions, which is not a good thing. Web components should be fully encapsulated and should not require users to have knowledge of their internals or manually manage dependencies on their behalf. However, this is a functionaing work around that can be used while we wait for Ivy, allowing us to get used to the web component pattern and work flows in the meantime.

In practice, what "externalizing the dependencies" actually means is listing them as npm peer dependencies of this project. A user of your web component will then be warned at npm install time that they must also load the dependent libraries. More on that in the usage section below.

Lastly, Clarity components are built with reference to a global style sheet, instead of using Shadow DOM. This means that the clarity style sheets are also externalized and must be loaded as global style sheets by the consuming app. Again, see usage below. This work around will need to remain in place until Clarity moves to using native encapsulation of styles.

Development

This starter simulates exporting a complex pre-existing component, without needing to change it, by wrapping that component, redefining its API in the wrapper and shimming any dependencies the component has on global services.

In this case the pre-existing component is the micro-frontend.component and it is wrapped by wrapper.component. The router service that micro-frontend.component uses is patched to make sure it never affects the browsers address bar, thereby keeping its routes internal. The wrapper.component exposes an API allowing the consuming application to programatically select its tabs, potentially linking them with the consuming apps router. The wrapped component continues to use both route and non-route based lazy loading internally.

When you are ready to test the actual web-component without relying on the Angular CLI, npm run build it. A sample web app to test it is provided in the root directory as index.html. Use the web server of your choice to load that up and test your web component.

Publishing

After you have run npm run build to build your component you will want to publish it to npm in order for it to be consumed by other web apps.

Use npm publish to publish your web component, after first modifying all relevant fields in package.json.

Usage

If you wish to use the demo web component exported by this module exactly as is, you can install it via

npm i @mcritch/clarity-webcomponent-starter

otherwise, npm install your web component from wherever you published it to.

At this time you will see warnings about the peer dependencies. The quickest way to resolve these is to directly copy the peerDependencies of this project to the dependencies section of your consuming app and then run npm install on that app again.

Next, you will need to actually load the dependencies. Depending on the tech stack of your consuming app, there are several ways this can be done. For example, you could import the depencies as modules in a javascript file that loads before any other. Alternatively, you could load them using script tags in your index.html. An example of a vanilla JS app doing this is given in the index.html file in the root directory. An example of a Vue.js app consuming web components built using this project can be found here: https://github.com/vigie/vue-web-components

After the dependencies are loaded, it is safe to load your web component and start using it in your app, interacting with it via the native web component API. As before, loading might be done via a javascript import, for example

import '@mcritch/clarity-webcomponent-starter';

or an index.html script tag, for example:

<script src="./dist/clarity-webcomponent-starter/main.js"></script>

Again, see the final script tag in index.html or https://github.com/vigie/vue-web-components for an example.

About


Languages

Language:TypeScript 71.8%Language:HTML 19.6%Language:JavaScript 8.3%Language:CSS 0.3%