Implementacja architektury wtyczek / systemu wtyczek / struktury wtykowej w Angular 2, 4, 5, 6

133

Aktualizacja 5/24/2018: Mamy teraz +3 wersje Angular z mojego oryginalnego postu i nadal nie mamy ostatecznego działającego rozwiązania. Lars Meijdam (@LarsMeijdam) zaproponował ciekawe podejście, które z pewnością warte jest zobaczenia. (Ze względu na problemy własnościowe musiał tymczasowo usunąć repozytorium GitHub, w którym pierwotnie opublikował swoją próbkę. Możesz jednak wysłać mu wiadomość bezpośrednio, jeśli chcesz otrzymać kopię. Aby uzyskać więcej informacji, zapoznaj się z komentarzami poniżej).

Niedawne zmiany architektoniczne w Angular 6 przybliżają nas do rozwiązania. Ponadto Angular Elements ( https://angular.io/guide/elements ) zapewnia pewną funkcjonalność komponentów - choć nie do końca to, co pierwotnie opisałem w tym poście.

Jeśli ktoś z niesamowitego zespołu Angular spotkał się z tym, pamiętaj, że wydaje się, że jest wiele innych osób, które również są bardzo zainteresowane tą funkcją. Warto wziąć pod uwagę zaległości.


Ja do zaimplementowania wtykowym (wtyczki) ramy w sposób Angular 2, Angular 4, Angular 5lub Angular 6aplikacji.

(Moim szczególnym przypadkiem użycia przy tworzeniu tego podłączanego frameworka jest to, że muszę opracować miniaturowy system zarządzania treścią. Z wielu powodów niekoniecznie tu omówionych, Angular 2/4/5/6jest on prawie idealny dla większości potrzeb tego systemu.)

Pod pojęciem struktury wtykanej (lub architektury wtyczek) rozumiem w szczególności system, który umożliwia deweloperom będącym osobami trzecimi tworzenie lub rozszerzanie funkcjonalności aplikacji podstawowej poprzez użycie podłączanych komponentów bez bezpośredniego dostępu lub znajomości kodu źródłowego aplikacji głównej. lub wewnętrzne funkcjonowanie .

(To sformułowanie o „ bez bezpośredniego dostępu lub wiedzy o kodzie źródłowym aplikacji lub jej wewnętrznym działaniu ” jest głównym celem).

Przykłady podłączanych struktur obejmują popularne systemy zarządzania treścią, takie jak WordPresslub Drupal.

Idealną sytuacją (tak jak w przypadku Drupala) byłoby proste umieszczenie tych podłączanych komponentów (lub wtyczek) w folderze, automatyczne ich wykrycie lub wykrycie przez aplikację i umożliwienie im magicznego „działania”. Gdyby to nastąpiło w sposób umożliwiający podłączanie na gorąco, co oznacza, że ​​aplikacja była uruchomiona, byłaby optymalna.

Obecnie próbuję ustalić odpowiedzi ( z Państwa pomocą ) na następujące pięć pytań.

  1. Praktyczność: czy struktura wtyczek dla Angular 2/4/5/6aplikacji jest w ogóle praktyczna? (Do tej pory nie znalazłem żadnego praktycznego sposobu na stworzenie prawdziwie podłączalnego frameworka za pomocą Angular2/4/5/6.)
  2. Oczekiwane wyzwania: Jakie wyzwania można napotkać podczas implementacji struktury wtyczek dla Angular 2/4/5/6aplikacji?
  3. Strategie wdrażania: Jakie konkretne techniki lub strategie można zastosować do implementacji struktury wtyczek dla Angular 2/4/5/6aplikacji?
  4. Sprawdzone metody : jakie są sprawdzone metody wdrażania systemu wtyczek do Angular 2/4/5/6aplikacji?
  5. Technologie alternatywne: jeśli struktura wtyczek nie jest praktyczna w Angular 2/4/5/6aplikacji, jakie stosunkowo równoważne technologie (np. React) Mogą być odpowiednie dla nowoczesnej, wysoce reaktywnej aplikacji internetowej ?

Ogólnie korzystanie z programu Angular 2/4/5/6jest bardzo pożądane, ponieważ:

  • jest naturalnie niesamowicie szybki - tak niesamowicie.
  • zużywa bardzo mało przepustowości (po początkowym załadowaniu)
  • ma stosunkowo niewielki ślad (po AOTi tree shaking) - i ten ślad nadal się kurczy
  • jest wysoce funkcjonalny, a zespół i społeczność Angular kontynuują szybki rozwój swojego ekosystemu
  • dobrze współpracuje z wieloma najlepszymi i najnowszymi technologiami internetowymi, takimi jak TypeScriptiObservables
  • Angular 5 obsługuje teraz pracowników usług ( https://medium.com/@webmaxru/a-new-angular-service-worker-creating-automatic-progressive-web-apps-part-1-theory-37d7d7647cc7 )
  • dzięki wsparciu Googlebędzie prawdopodobnie wspierany i ulepszany w przyszłości

Bardzo chciałbym użyć Angular 2/4/5/6w moim obecnym projekcie. Jeśli będę mógł używać Angular 2/4/5/6, będę również używać Angular-CLIi prawdopodobnie Angular Universal(do renderowania po stronie serwera).

Oto moje dotychczasowe przemyślenia dotyczące powyższych pytań. Przejrzyj i przekaż swoją opinię i oświecenie.

  • Angular 2/4/5/6aplikacje zużywają pakiety - ale niekoniecznie oznacza to to samo, co zezwalanie na wtyczki w aplikacji. Wtyczkę w innych systemach (np. Drupal) Można zasadniczo dodać, upuszczając folder wtyczek do wspólnego katalogu modułów, skąd jest automatycznie „pobierany” przez system. W programie Angular 2/4/5/6pakiet (tak jak może to być wtyczka) jest zwykle instalowany przez npm, dodawany do package.json, a następnie ręcznie importowany do aplikacji - jak w app.module. Jest to znacznie bardziej skomplikowane niż Drupalmetoda upuszczenia folderu i automatycznego wykrycia pakietu przez system. Im bardziej skomplikowana jest instalacja wtyczki, tym rzadziej ludzie będą z niej korzystać. Byłoby znacznie lepiej, gdyby istniał sposóbAngular 2/4/5/6aby automatycznie wykrywać i instalować wtyczki. Jestem bardzo zainteresowany znalezieniem metody, która pozwala osobom niebędącym programistami zainstalować Angular 2/4/5/6aplikację i zainstalować dowolne wybrane wtyczki bez konieczności rozumienia całej architektury aplikacji.

  • Ogólnie rzecz biorąc, jedną z korzyści płynących z zapewniania architektury z możliwością podłączania jest to, że deweloperzy zewnętrzni mogą bardzo łatwo rozszerzyć funkcjonalność systemu. Oczywiście ci programiści nie będą zaznajomieni ze wszystkimi zawiłościami kodu aplikacji, do której się podłączają. Po opracowaniu wtyczek inni, nawet mniej techniczni użytkownicy mogą po prostu zainstalować aplikację i wybrane wtyczki. Jest jednak Angular 2/4/5/6stosunkowo skomplikowany i wymaga bardzo długiej nauki. Aby jeszcze bardziej skomplikować rzeczy, większość produkcji Angular 2/4/5/6aplikacje również wykorzystać Angular-CLI, Angular Universali WebPack. Ktoś, kto wdraża wtyczkę, prawdopodobnie musiałby mieć przynajmniej podstawową wiedzę o tym, jak wszystkie te elementy pasują do siebie - wraz z solidną praktyczną znajomościąTypeScripti rozsądną znajomość NodeJS. Czy wymagania dotyczące wiedzy są tak ekstremalne, że żadna osoba trzecia nie chciałaby nigdy opracować wtyczki?

  • Większość wtyczek będzie prawdopodobnie miała jakiś komponent po stronie serwera (np. Do przechowywania / pobierania danych związanych z wtyczkami), jak również pewne dane wyjściowe po stronie klienta. Angular 2/4/5w szczególności (i zdecydowanie) zniechęca programistów do wstrzykiwania własnych szablonów w czasie wykonywania - ponieważ stwarza to poważne zagrożenie bezpieczeństwa. Aby obsłużyć wiele typów danych wyjściowych, które może obsłużyć wtyczka (np. Wyświetlanie wykresu), wydaje się, że prawdopodobnie konieczne jest umożliwienie użytkownikom tworzenia treści, które są wprowadzane do strumienia odpowiedzi, w jednej postaci. Zastanawiam się, jak można by zaspokoić tę potrzebę bez obrazowego niszczenia Angular 2/4/5/6mechanizmów bezpieczeństwa.

  • Większość Angular 2/4/5/6aplikacji produkcyjnych jest wstępnie kompilowana przy użyciu kompilacji Ahead of Time( AOT). (Prawdopodobnie wszystko powinno być.) Nie jestem pewien, w jaki sposób można dodać (lub zintegrować) wtyczki do wstępnie skompilowanych aplikacji. Najlepszy scenariusz obejmowałby kompilację wtyczek oddzielnie od głównej aplikacji. Jednak nie jestem pewien, jak to działa. Rozwiązaniem alternatywnym może być ponowna kompilacja całej aplikacji z dołączonymi wtyczkami, ale to trochę komplikuje sprawę dla administratora, który po prostu chce zainstalować aplikację (na swoim serwerze) wraz z dowolnymi wybranymi wtyczkami.

  • W Angular 2/4/5/6aplikacji, zwłaszcza wstępnie skompilowanej, pojedynczy fragment błędnego lub powodującego konflikt kodu może spowodować uszkodzenie całej aplikacji. Angular 2/4/5/6aplikacje nie zawsze są najłatwiejsze do debugowania. Zastosowanie źle zachowanych wtyczek może spowodować bardzo nieprzyjemne doznania. Obecnie nie jestem świadomy istnienia mechanizmu do wdzięcznej obsługi źle zachowujących się wtyczek.

Anthony Gatlin
źródło
1
Moim zdaniem moduł kątowy 2 jest wtyczką. @ angular / router, @ angular / form, @ angular / http, @ angular / material, to są „wtyczki” firmy angular, możemy sprawdzić, jak tworzą „wtyczki”.
Timathon,
8
@Timathon, niestety, nie są takie same. Systemy wtyczek pozwalają na rozszerzenie aplikacji bez modyfikacji podstawowego kodu aplikacji. Użycie @ angular / router, @ angular / form, itp. Wymaga od użytkownika modyfikacji aplikacji. To naprawdę biblioteki, a nie wtyczki. Naprawdę bardziej interesuje mnie umożliwienie użytkownikom administracyjnym niebędącym programistami wybierania i korzystania z wtyczek, które są dla nich najciekawsze, bez konieczności poznawania wewnętrznych szczegółów aplikacji.
Anthony Gatlin,
1
Czy coś z tym osiągnąłeś? Chcę spróbować czegoś podobnego. Sposób budowania Angular 2 (wokół modułów) Myślałem, że architektura typu plugin będzie do niego pasować, ale nie ma żadnych przykładów itp.
Joe
2
@Joe, nadal nie mam dobrego rozwiązania tego problemu. Myślałem tak samo jak ty.
Anthony Gatlin,
2
Stworzyłem repozytorium na githubie z rozwiązaniem, które może pomóc. Używa bibliotek Angular 6 i 1 aplikacji bazowych, które leniwie ładują dołączone biblioteki UMD; github.com/lmeijdam/angular-umd-dynamic-example Jeśli masz jakieś sugestie, możesz je dodać!
Lars Meijdam

Odpowiedzi:

17

Stworzyłem repozytorium na githubie z rozwiązaniem, które może pomóc. Używa bibliotek Angular 6 i 1 aplikacji bazowych, które leniwie ładują dołączone biblioteki UMD; https://github.com/lmeijdam/angular-umd-dynamic-example

Jeśli masz jakieś sugestie, możesz je dodać!

Lars Meijdam
źródło
2
Jak wspomniano w innym komentarzu, musiałem ustawić repozytorium jako prywatne ze względu na politykę firmy. Umieszczę je z powrotem w Internecie później, ponieważ trwają dyskusje
Lars Meijdam
Bardzo chciałbym zobaczyć Twoje rozwiązanie.
Subhan Ahmed
@Subhan, jestem obecnie zajęty przepisywaniem repozytorium przed ponownym umieszczeniem go na GH. Daj mi trochę więcej czasu. W przeciwnym razie możesz się ze mną skontaktować bezpośrednio! : D
Lars Meijdam
@ lars-meijdam: nadal będziemy dużo czekać: D ... Ja też jestem bardzo zainteresowany. Z góry
dziękuję
17

🛠️ Github Demo Angular-Plugin Architecture

Może Ivy może coś zmienić, ale na razie korzystam z rozwiązania wykorzystującego Angular CLI Custom Builder i spełniającego następujące wymagania:

  • AOT
  • unikaj duplikatów kodu (pakiety takie jak @ angular / core {common, form, router}, rxjs, tslib)
  • używaj współdzielonej biblioteki we wszystkich wtyczkach, ale NIE WYSYŁAJ wygenerowanych fabryk z tej wspólnej biblioteki w każdej wtyczce, ale raczej ponownie wykorzystaj kod biblioteki i fabryki
  • ten sam poziom optymalizacji, jaki daje nam Angular CLI
  • Aby zaimportować zewnętrzne moduły, wystarczy wiedzieć tylko jedno: ścieżkę do pliku pakietu
  • nasz kod powinien rozpoznać moduł i umieścić wtyczkę na stronie
  • obsługuje renderowanie po stronie serwera
  • ładuj moduł tylko w razie potrzeby

Użycie jest proste, ponieważ:

ng build --project plugins --prod --modulePath=./plugin1/plugin1.module#Plugin1Module 
         --pluginName=plugin1 --sharedLibs=shared --outputPath=./src/assets/plugins

Więcej na ten temat w moim artykule:

yurzui
źródło
Świetny przykład! Jedno pytanie. Jak mogę przejść OAuthTokenw czasie wykonywania do usługi bibliotecznej z naszej głównej aplikacji?
yogen darji
@yurzui czy możemy zastosować to samo podejście, jeśli mamy wiele aplikacji kątowych i używamy ich całej dystrybucji zamiast tworzenia modułów, takich jak plugin 1 i plugin 2?
Momin Shahzad
Czy byłbyś w stanie ponownie odwiedzić ten przykład i dostosować go do Ivy w najbliższej przewidywalnej przyszłości? Jeśli chcesz, dodaj przykład udostępnionej usługi i udostępnionej, InjectionTokenktóra zostanie dostarczona w AppModule i wstrzyknięta w innych wtyczkach. Dzięki!
Jyrkka
11

Właśnie opublikowałem nowy rozdział w mojej książce „ Developing with Angular ”, który porusza temat wtyczek w Angular 2+ i powinien być bardzo interesujący dla osób, które próbują tworzyć zewnętrzne wtyczki.

Kluczowe punkty:

  • Wtyczki
  • Budowanie komponentów na podstawie nazw ciągów
  • Ładowanie konfiguracji ze źródeł zewnętrznych
  • Dynamicznie zmieniające się trasy aplikacji
  • Wtyczki zewnętrzne
  • Tworzenie bibliotek wtyczek
  • Ładowanie wtyczek do aplikacji
  • Dynamiczne trasy z zawartością wtyczki

Książkę można dostać bezpłatnie i ma model „płać, co chcesz”. Zapraszam do pobrania kopii i mam nadzieję, że to pomoże.

Denys Vuika
źródło
Jak mogę zastąpić komponent podrzędny architekturą wtyczki przedstawioną w książce? Wymienię szablon lub może dodam właściwość wejściową ecc ... Jednocześnie muszę wiedzieć, czy istnieje sposób na nadpisanie / rozszerzenie świadczonej usługi.
Matteo Calò
1
@Denis Vuyka, Książka wygląda świetnie, ale brakuje jej najważniejszej części - wsparcia dla kompilacji AoT.
Sergey Sokolov
7

Przykładowa aplikacja z działającym systemem wtyczek (dzięki Gijs za założenie repozytorium github!) Https://github.com/PacktPublishing/Mastering-Angular-2-Components/tree/master/angular-2-components-chapter-10 w oparciu w eBooku Mastering Angular 2 Components

  • architektura wtyczek w celu rozszerzenia podstawowych komponentów aplikacji
  • system wtyczek plików (do prostego dodawania katalogów / plików wtyczek bez edytowania podstawowych plików konfiguracyjnych lub konieczności ponownej kompilacji aplikacji!)
  • ładuj i dynamicznie używaj wtyczek
  • budowanie podstawowego menedżera wtyczek do aktywowania / dezaktywowania wtyczek w locie

Pozdrawiam, Niklas

Niklas Teich
źródło
2
Nie widzisz przykładowego kodu z tego linku, czy możesz opublikować Code Pen lub JSFiddle?
Sean Chase
4
Przeczytałem książkę, ale część dotycząca wtyczek jest nieaktualna. Używa zwykłego JS i SystemJS, podczas gdy Angular zmierza w kierunku Typescript i Webpack. Używając WebPacka i Maszynopisu wydaje się to nieosiągalne, wysłałem pytanie na wypadek, gdybyś znalazł jakieś rozwiązania. Oto link
Luigi Dallavalle
To powinno pomóc: github.com/mgechev/angular-seed/issues/…
Guillaume
czy ktoś może potwierdzić czy powyższe działa? A co jeśli nie chcemy używać systemjs
django
5

To, czego szukasz, to leniwe ładowanie modułu. Oto przykład: http://plnkr.co/edit/FDaiDvklexT68BTaNqvE?p=preview

import {Component} from '@angular/core';
import {Router} from '@angular/router';

@Component({
  selector: 'my-app',
  template: `
    <a [routerLink]="['/']">Home</a> | 
    <a [routerLink]="['/app/home']">App Home</a> |
    <a [routerLink]="['/app/lazy']">App Lazy</a>

    <hr>
    <button (click)="addRoutes()">Add Routes</button>

    <hr>
    <router-outlet></router-outlet>
  `
})
export class App {
  loaded: boolean = false;
  constructor(private router: Router) {}

  addRoutes() {
    let routerConfig = this.router.config;

    if (!this.loaded) {
      routerConfig[1].children.push({
        path: `lazy`,
        loadChildren: 'app/lazy.module#LazyModule'
      });

      this.router.resetConfig(routerConfig);
      this.loaded = true;
    }
  }
}

Najlepsze ... Tom

Tom I
źródło
17
Dziękuję za poświęcenie czasu na odpowiedź na moje pytanie. Jestem zaznajomiony z leniwie ładowanymi modułami, ale nie są to do końca to, czego szukam. Leniwie ładowane moduły muszą być nadal znane w czasie projektowania. Chcę mieć możliwość dodania rzeczywistych modułów i funkcji, o których nie wiadomo lub nie przewidywano podczas tworzenia oryginalnej aplikacji. (Poszukuję czegoś nieco bardziej dynamicznego.) Z pewnością te komponenty wykorzystywałyby (jakąś formę) leniwego ładowania, ale to tylko jeden mały element układanki. Jeszcze raz dziękuję za udostępnienie tej odpowiedzi.
Anthony Gatlin
1
Zgadzam się, że to nie odpowiada na pytanie. Leniwe ładowanie nie pomaga w architekturze wtyczek, ponieważ są one wymagane w czasie projektowania. Po prostu nie pobiera / nie przesyła danych do klienta, dopóki nie są wymagane.
Joe
Co się stanie, jeśli Twoja aplikacja będzie wiedzieć o wszystkich dostępnych modułach wtyczek w czasie kompilacji. W momencie dodawania nowego modułu do platformy należy go przekompilować z tym modułem. Tylko pomysł ... Nie jestem pewien, czy to znacznie zwiększy rozmiar plików JS, nie jestem pewien, czy funkcja leniwego ładowania umieści taki moduł w oddzielnym pliku, a następnie leniwie go załaduje, po prostu dzielę się swoim pomysłem ...
Vladimir Prudnikov
@VladimirPrudnikov, gdyby aplikacja mogła wiedzieć o wszystkich wtyczkach w czasie kompilacji, byłoby fantastycznie. Chodzi jednak o to, aby móc dodawać wtyczki prawdopodobnie po skompilowaniu aplikacji. Pozwoliłoby to na prawdziwie dynamiczne podłączanie modułów. Wymagałoby to jednak wstępnej kompilacji modułów w momencie ich wdrażania - i nie jestem pewien, jak to by działało. Nie jestem też pewien, jak zachować wersję modułów wtyczek kompatybilną z Angularem.
Anthony Gatlin
2

Zrobiłem hack do ładowania i kompilowania innych modułów w czasie ładowania początkowego, ale nie rozwiązałem problemu cyklicznych zależności

 const moduleFile: any = require(`./${app}/${app}.module`),
                    module = moduleFile[Object.keys(moduleFile)[0]];

 route.children.push({
     path: app,
     loadChildren: (): Promise<any> => module
 });
 promises.push(this.compiler.compileModuleAndAllComponentsAsync(module));

następnie w AppModule dodaj to:

{
        provide: APP_INITIALIZER,
        useFactory: AppsLoaderFactory,
        deps: [AppsLoader],
        multi: true
},
Jose Luis Berrocal
źródło
2

Szukałem również systemu wtyczek w kątowym 2/4 do tworzenia środowiska RAD dla aplikacji korporacyjnej w pracy. Po kilku badaniach zdecydowałem się zaimplementować kolekcję przechowywanych w bazie danych (ale mogą znajdować się w systemie plików) komponentów pseudo-Angular.

Komponenty przechowywane w bazie danych są oparte na ng-dynamic, a implementacja głównego komponentu jest podobna do tej:

declare var ctx: any;

@Component({
    selector: 'my-template',
    template: `
<div>
    <div *dynamicComponent="template; context: { ctx: ctx };"></div>
</div>
  `,
    providers: [EmitterService],

})

export class MyTemplateComponent implements OnMount, AfterViewInit, OnChanges {


    // name
    private _name: string;
    get name(): string {
        return this._name;
    }
    @Input()
    set name(name: string) {
        this._name = name;        
        this.initTemplate();
    }

    template: string;
    ctx: any = null;

    private initTemplate() {

        this.templateSvc.getTemplate(this.name).subscribe(res => {
            // Load external JS with ctx implementation
            let promise1 = injectScript(res.pathJs);
            // Load external CCS
            let promise2 = injectScript(res.pathCss);

            Promise.all([promise1, promise2]).then(() => {

                // assign external component code
                this.ctx = ctx; //

                // sets the template
                this.template = res.template;

                this.injectServices();

                if (this.ctx && this.ctx.onInit) {
                    this.ctx.onInit();
                }

            });

        });

    }

Zewnętrzny kod javascript jest podobny do komponentów kątowych:

var ctx = {

// injected    
_httpService: {},
_emitterService: null,

// properies
model: {
    "title": "hello world!",
},


// events
onInit() {
    console.log('onInit');
},

onDestroy() {
    console.log('onDestroy');
},

onChanges(changes) {
    console.log('changes', changes);
},

customFunction1() {
    console.log('customFunction1');
},

childTemplateName: string = 'other-component'; 

};

A szablony komponentów są jak szablony kątowe:

<a (click)="customFunction1()">{{ ctx.model.title }}</a>
<input [(ngModel)]="ctx.model.title" type="text" />

I może być również zagnieżdżony:

<a (click)="customFunction1()">{{ ctx.model.title }}</a>
<my-template [name]="childTemplateName"></my-template>

Chociaż nie jest to idealne rozwiązanie, twórcy niestandardowych komponentów mają podobną strukturę niż w angular2 / 4.

zarpilla
źródło
2

Można to zrobić „ręcznie”. Ponieważ webpack nie wie nic o zewnętrznym module (wtyczkach), nie może uwzględnić ich w paczce (pakietach). Więc spojrzałem na kod wygenerowany przez webpack i znalazłem ten fragment kodu w main.bundle.js:

var map = {
"./dashboard/dashboard.module": ["../../../../../src/app/dashboard/dashboard.module.ts","dashboard.module"]}; 

Sprawdźmy, co zawiera ta tablica:

  1. "./dashboard/dashboard.module" - to jest URL routingu modułu, który chcemy leniwie załadować, na przykład: {path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule'}
  2. „../../../../../src/app/dashboard/dashboard.module.ts” - to jest punkt wejścia (konstruktor) pobiera z
  3. „dashboard.module” - rzeczywista nazwa pliku bez fragmentu.js (na przykład: dashboard.module.chunk.js )

Więc teoretycznie, jeśli dodasz wpis do właściwości mapy, skonfigurujesz routing i będziesz postępować zgodnie z wzorcem, możesz mieć system wtyczek. Teraz wyzwaniem jest dodanie lub usunięcie wpisów z tej właściwości mapy. Oczywiście nie można tego zrobić z kodu kątowego, należy to zrobić dla narzędzia zewnętrznego.

Niki Uzun
źródło
2

Próbowałem zaimplementować architekturę wtyczek z wykorzystaniem ABP, Angular i ASP.NET Core: https://github.com/chanjunweimy/abp_plugin_with_ui

Zasadniczo opracowałem wtyczki kątowe przy użyciu różnych aplikacji kątowych, a następnie dynamicznie je dodaję.

Więcej informacji o tym, jak to osiągam:

Mam 2 aplikacje angular-cli, 1 to główna aplikacja angular cli, a druga to aplikacja angular cli plugin. Problem, z którym mamy do czynienia w podejściu do architektury wtyczek Angular-cli, polega na tym, jak je integrujemy.

W tej chwili uruchomiłem ng-build na obu aplikacjach i umieściłem je w folderze „wwwroot”, który następnie był hostowany na serwerze ASP.NET core 2.0. Prostszym repozytorium, które pokazuje ten pomysł, jest Angular Multiple App: https://github.com/chanjunweimy/angular-multiple-app

abp_plugin_with_ui to repozytorium, które pracuje nad rozwojem wtyczki, która zawiera zarówno backend, jak i interfejs CLI Angulara. W przypadku backendu wykorzystałem framework aspnetboilerplate, którego frontend jest rozwijany przy użyciu wielu aplikacji angular-cli.

Aby główna aplikacja była zintegrowana z aplikacją wtyczki, musimy uruchomić "ng-build" na obu aplikacjach (pamiętaj, że musimy również zmienić na href aplikacji wtyczki), a następnie przenosimy zbudowaną zawartość wtyczki angular cli, do folderu głównego aplikacji "wwwroot". Po osiągnięciu tego wszystkiego możemy uruchomić „dotnet run”, aby obsługiwać aplikację sieci Web ASP.NET Core 2.0 w celu hostowania plików statycznych generowanych przez „ng build”.

Mam nadzieję, że to pomoże. Wszelkie komentarze są mile widziane! ^^

Junwei Chan
źródło
Próbuję postępować zgodnie z dokumentacją wtyczki, ale myślę, że dokumentacja pomija kilka kroków. Przepraszam, jeśli źle to odczytam. Cały fragment „dodawania wtyczki” nie jest dla mnie jasny. Podążałem za tym krok po kroku, ale tak naprawdę nie widzę rezultatów. Co powinienem zobaczyć na porcie 4200 po uruchomieniu powłoki zasilania? Nie widzę folderu wtyczek w /aspnet-core/src/Todo.MainProject.Web.Host/. Uruchomiłem program PowerShell i ten folder nie został utworzony. Każda pomoc doceniona. Myślę, że twoje podejście jest tym, czego potrzebuję, ale jestem trochę niejasny, jak to działa.
Brian Kitt,
Dobrze. Powinienem był to zrobić, zanim zadam pytanie. Spędziłem czas na debugowaniu i wymyśliłem odpowiedzi. # 1) PowerShell nie umieszcza pliku .zip w odpowiednim miejscu, muszę utworzyć folder z wtyczkami i przenieść plik zip. # 2) po uruchomieniu aplikacji kątowej dynamicznie wywołuje program ładujący i kopiuje wtyczki do katalogu głównego. To było trochę przeliterowane, ale teraz rozumiem. # 3) Muszę użyć adresu URL, aby wywołać wtyczkę, nigdzie nie pojawia się. Spodziewałem się, że będzie na desce rozdzielczej. Dziękuję za twoją pracę, to jest znaczący fragment kodu.
Brian Kitt
2

Trochę poza tematem, ale biblioteki komponentów UI mogą być interesujące dla niektórych czytelników, którzy szukają wtyczek:
https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the -angular-cli-and-ng-packagr-53b2ade0701e

NativeScript ma wbudowane wtyczki UI:
https://docs.nativescript.org/plugins/building-plugins
Te wtyczki wymagają Angular Wrapper:
https://docs.nativescript.org/plugins/angular-plugin

RaSor
źródło
2

Jestem obecnie w tym samym zadaniu co ty, próbuję stworzyć podłączalną / motywowalną wersję Angulara i nie jest to trywialny problem.

Właściwie znalazłem całkiem dobre rozwiązania, czytając książkę Developing with Angular autorstwa Geniusa Denysa Vuyiki , on w tej książce wyjaśnia całkiem dobre rozwiązanie, mówi o wtyczkach zewnętrznych na stronie 356 książki i Uses Rollup.js, aby osiągnąć rozwiązanie, następnie przetwarza dynamiczne ładowanie zewnętrznych wtyczek, które zostały wcześniej zbudowane poza aplikacją.

Istnieją również dwie inne biblioteki / projekty, które pomagają osiągnąć ten wynik ng-packagr i rozszerzenia Nx dla Agnular (od Nrwl) próbujemy zaimplementować to drugie, i powiedziałbym, że nie jest tak gładki, jak się spodziewaliśmy, angular był prosty nie jest do tego skonstruowany, więc musimy popracować nad niektórymi podstawami dotyczącymi tego, jak Angular i NX ppl są jednymi z najlepszych na nim.

Jesteśmy dopiero na początku naszego projektu Open Source, używamy Django + Mongo + Angular ( nazywamy WebDjangular i jednym z naszych możliwych podejść do tej odpowiedzi jest to, że Django będzie musiało napisać kilka plików konfiguracyjnych JSON i zbudować aplikacja za każdym razem, gdy zostanie zainstalowana i aktywowana nowa wtyczka lub motyw.

To, co już osiągnęliśmy, to z bazy danych możemy użyć tagów dla komponentów, takich jak we wtyczce, a komponent zostanie wydrukowany na ekranie! Ponownie projekt jest na bardzo wczesnym etapie, opieramy nieco naszą architekturę na Wordpressie i mamy dużo więcej testów do wykonania, aby spełnić nasze marzenie: D

Mam nadzieję, że książka może ci pomóc, a korzystając z Rollup.js wiem, że będziesz w stanie rozwiązać ten nietrywialny problem.

Paulo Peres Junior
źródło