Skip to content

Latest commit

 

History

History
217 lines (153 loc) · 5.28 KB

File metadata and controls

217 lines (153 loc) · 5.28 KB

Web Components with Angular

Micro-frontends with Angular Web Components

Init application

cd angular
npm i
npm run build:web-components
cd ../vanilla
open index.html

How to build this application from scratch

Angular configuration

1. Init angular project with

I decided to name application angular, so

ng new angular
cd angular

2. Create and customize your components that you want ot use as web components

  • Created alert component

  • Created alert service

  • I used @angular/material to create components with schematics:

    • navigation

      defining input and output

    angular/src/app/navigation/navigation.component.ts

    export class NavigationComponent {
      @Input() sidebarTitle = 'Menu';
      @Input() toolbarTitle = 'App';
    
      @Output() linkSelected = new EventEmitter<number>();
    
      ...
    }

    I have created example layout inside angular/src/app/app.component.html, so to check how it works insure that it is bootstrapped:

    angular/src/app/app.module.ts

    @NgModule({
      ...
      bootstrap: [AppComponent],
      ...
    })
ng add @angular/elements

Configuring:

import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [],
  providers: [],
  // clear bootstrap array before build!
  bootstrap: [],
})
export class AppModule {
  constructor(private injector: Injector) {}

  ngDoBootstrap() {
    // use @angular/elements function to create custom element
    const customComponent = createCustomElement(AppComponent, {
      injector: this.injector,
    });

    // define custom element with browser api in kebab-case (important, 2+ words)
    customElements.define('ng-custom-component', customComponent);
  }
}
ng add ngx-build-plus
  • Add new scripts to your package.json

package.json

"scripts": {
  /*...*/
  "build:prod:no-hashes": "ng build --prod --output-hashing none --single-bundle true",
  "build:package-bundle": "cat dist/angular/{polyfills,main}.js > dist/angular/bundle.js",
  "build:web-components": "npm run build:prod:no-hashes && npm run build:package-bundle",
  "build:web-components:serve": "npm run build:prod:no-hashes && serve -l 5001 dist/angular"
}

Run build:web-components script to build project and generate angular/dist/angular/bundle.js

5. Because I use material, I must cut all links with stylesheet from angular/src/index.html and paste it to styles file

styles.css

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap');
@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
@import url('https://fonts.gstatic.com');

Vanilla configuration

Import /angular/dist/angular/bundle.js into your second application. After building, your /angular/dist/angular/styles.css might be empty, so skip it, if not, you must import also import it

Please look into your built angular html file to check what you also need to import to your vanilla project or to your angular styles file

There are 2 ways to connect angular bundle into your app:

1. By importing url into script file while serving angular builded project (not my way):
cd angular
npm run build:web-components:serve

Then copy all script imports from angular/dist/angular/index.html (there are more then two) inside your vanilla file:

<script src="polyfills.js"></script>
<script src="main.js"></script>

THEN ADD http://localhost:5001/ TO SCRIPT FILES:

<script src="http://localhost:5001/polyfills.js"></script>
<script src="http://localhost:5001/main.js"></script>

Also import all styles

<script src="http://localhost:5001/styles.css"></script>
2. By importing builded bundle .js file

What I did inside vanilla html:

  • Add css angular build
<head>
  ...
  <link rel="stylesheet" href="../angular/dist/angular/styles.css" />
</head>
  • Connect builded angular .js file into top of the body
<body>
  <script src="../angular/dist/angular/bundle.js"></script>
  ...
</body>
  • Add custom elements to html
<ng-alert></ng-alert>
<ng-navigation toolbar-title="Vanilla Toolbar"></ng-navigation>
  • Add event listener to output prop inside script tag | file
const nav = document.querySelector('ng-navigation');
nav.addEventListener('linkSelected', alert);

Resources I used: