Skip to content

Instantly share code, notes, and snippets.

@tsabirgaliev
Last active January 4, 2019 01:40
Show Gist options
  • Star 17 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tsabirgaliev/6eeb35ca3ee1a857d3b63d81311a985e to your computer and use it in GitHub Desktop.
Save tsabirgaliev/6eeb35ca3ee1a857d3b63d81311a985e to your computer and use it in GitHub Desktop.
Angular example plugin architecture
import { Component, Compiler, Injector, ReflectiveInjector } from '@angular/core';
import { ViewContainerRef, ViewChild } from '@angular/core';
import { COMPILER_PROVIDERS } from '@angular/compiler';
import * as AngularCore from '@angular/core';
import * as AngularCommon from '@angular/common';
@Component({
selector: 'app-root',
template: `
<h1>
{{title}}
</h1>
<input type="text" [(ngModel)]="href" size="50">
<button (click)="load()">Load</button>
<ng-template #pluginHost>
Here be dragons
</ng-template>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
href = 'http://localhost:4200/assets/lazy.module.js';
@ViewChild('pluginHost') pluginHost;
private injector: Injector;
private compiler: Compiler;
constructor(injector: Injector, private _vcr: ViewContainerRef) {
this.injector = ReflectiveInjector.resolveAndCreate(COMPILER_PROVIDERS, injector);
this.compiler = this.injector.get(Compiler);
}
load() {
fetch(this.href)
.then(response => response.text())
.then(source => {
const exports = {}; // this will hold module exports
const modules = { // this is the list of modules accessible by plugin
'@angular/core': AngularCore,
'@angular/common': AngularCommon
};
const require = (module) => modules[module]; // shim 'require'
eval(source); // interpret the plugin source
const mwcf = this.compiler.compileModuleAndAllComponentsSync(exports['PluginModule']);
const componentFactory = mwcf.componentFactories
.find(e => e.selector === 'app-plugin-component'); // find the entry component
if (componentFactory) {
this._vcr.clear();
const componentRef = this._vcr.createComponent(componentFactory);
componentRef.instance.data = 'Some Data';
}
});
}
}
> tsc --lib es2016,dom --experimentalDecorators true --emitDecoratorMetadata true lazy.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-plugin-component',
template: `
<p>
lazy works! {{data}}
</p>
`
})
export class PluginComponent implements OnInit {
type: "PluginComponent";
data: string = "Hello!";
ngOnInit() {
}
}
@NgModule({
imports: [
CommonModule,
],
declarations: [ PluginComponent ],
entryComponents: [ PluginComponent ]
})
export class PluginModule { }
@MartinSvarrer
Copy link

Thanks looks like a great start. Will have a close look.r

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment