I built a simple Web Component via Angular using Pascal Precht\'s tutorial, which you can see working HERE. It auto-magically compiles in the on Stackblitz in the link, but not
Current Angular version doesn’t provide an option to export component as single local file which can used in any non angular application. However it can be achieved by making changes in building and deployment steps. In my example I have created two angular elements a button and alert message. Both components are compiled and exported as single local file which I’m loading in a plain html file with javascript.
Here are the steps follows: 1. Add ButtonComponent and AlertComponent in entryComponent list. In ngDoBootstrap and define them as custom elements. This is how my app.module looks:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';
import { ButtonComponent } from './button/button.component';
import { AlertComponent } from './alert/alert.component';
@NgModule({
declarations: [AppComponent, ButtonComponent, AlertComponent],
imports: [BrowserModule],
entryComponents: [ButtonComponent, AlertComponent]
})
export class AppModule {
constructor(private injector: Injector) {
}
ngDoBootstrap() {
const customButton = createCustomElement(ButtonComponent, { injector: this.injector });
customElements.define('my-button', customButton);
const alertElement = createCustomElement(AlertComponent, { injector: this.injector});
customElements.define('my-alert', alertElement);
}
}
import {
Input,
Component,
ViewEncapsulation,
EventEmitter,
Output
} from '@angular/core';
@Component({
selector: 'custom-button',
template: ``,
styles: [
`
button {
border: solid 3px;
padding: 8px 10px;
background: #bada55;
font-size: 20px;
}
`
],
encapsulation: ViewEncapsulation.Native
})
export class ButtonComponent {
@Input() label = 'default label';
@Output() action = new EventEmitter();
private clicksCt = 0;
handleClick() {
this.clicksCt++;
this.action.emit(this.clicksCt);
}
}
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'alert-message',
template: 'Alert Message: {{message}}',
styles: [
`
div {
border: 1px solid #885800;
background-color: #ffcd3f;
padding: 10px;
color: red;
margin:10px;
font-family: Arial;
}
`]
})
export class AlertComponent {
@Input () message: string;
}
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.css"],
"scripts": [
{
"input":
"node_modules/document-register-element/build/document-register-element.js"
}
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "angular6-elements:build"
},
"configurations": {
"production": {
"browserTarget": "angular6-elements:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angular6-elements:build"
}
}
runtime, polyfills, script
js files into single script file and export elements.js
which contains the custom elements
(optional: gzip those files)
serve it using http-server deploy --gzip"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod --output-hashing=none",
"package": "npm run package-base && npm run package-elements",
"package-base": "cat dist/{runtime,polyfills,scripts}.js | gzip > deploy/script.js.gz",
"package-elements": "cat dist/main.js | gzip > deploy/elements.js.gz",
"serve": "http-server deploy --gzip",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}
script.js
and elements.js
in index.html (in deploy directory) to tell the browser about the custom elements.
Now my-button and my-alert can be included in index.html
. In this example, the button is shown on-load and Alert message is added dynamically (with counter number) on click of the button.
Here is the code:
Custom Button Test Page
Here is my link for my git repo
Hope this will help!
Thanks.