Implémentation d'une architecture de plugin / système de plugin / framework enfichable dans Angular 2, 4, 5, 6

133

Mise à jour du 24/05/2018: Nous sommes maintenant +3 versions d'Angular à partir de mon article d'origine et n'avons toujours pas de solution finale viable. Lars Meijdam (@LarsMeijdam) a proposé une approche intéressante qui vaut certainement le détour. (En raison de problèmes de propriété, il a dû supprimer temporairement le référentiel GitHub où il avait initialement publié son échantillon. Cependant, vous pouvez lui envoyer un message directement si vous souhaitez une copie. Veuillez consulter les commentaires ci-dessous pour plus d'informations.)

Les récents changements architecturaux dans Angular 6 nous rapprochent d'une solution. De plus, Angular Elements ( https://angular.io/guide/elements ) fournit certaines fonctionnalités de composant - mais pas tout à fait ce que j'ai décrit à l'origine dans cet article.

Si quelqu'un de l'incroyable équipe Angular rencontre cela, veuillez noter qu'il semble y avoir beaucoup d'autres personnes qui sont également très intéressées par cette fonctionnalité. Cela vaut peut-être la peine d'envisager l'arriéré.


Je souhaite mettre en place un cadre enfichable (plug-in) dans un Angular 2, Angular 4, Angular 5, ou Angular 6application.

(Mon cas d'utilisation spécifique pour développer ce cadre enfichable est que je dois développer un système de gestion de contenu miniature. Pour un certain nombre de raisons qui ne sont pas nécessairement développées ici, il Angular 2/4/5/6correspond presque parfaitement à la plupart des besoins de ce système.)

Par framework enfichable (ou architecture de plug-in), j'entends spécifiquement un système qui permet aux développeurs tiers de créer ou d'étendre les fonctionnalités d'une application principale grâce à l'utilisation de composants enfichables sans avoir un accès direct ou une connaissance du code source de l'application principale. ou fonctionnement interne .

(Cette formulation à propos de " sans avoir un accès direct ou une connaissance du code source ou du fonctionnement interne de l'application " est un objectif fondamental.)

Des exemples de cadres enfichables comprennent des systèmes de gestion de contenu courants tels que WordPressou Drupal.

La situation idéale (comme avec Drupal) serait de pouvoir simplement placer ces composants enfichables (ou plug-ins) dans un dossier, faire en sorte que l'application les détecte ou les découvre automatiquement et les fasse «fonctionner» comme par magie. Cela se produirait d'une manière enfichable à chaud, c'est-à-dire pendant que l'application s'exécutait, serait optimal.

J'essaie actuellement de déterminer les réponses ( avec votre aide ) aux cinq questions suivantes.

  1. Praticité: un framework de plugin pour une Angular 2/4/5/6application est-il même pratique? (Jusqu'à présent, je n'ai trouvé aucun moyen pratique de créer un framework vraiment connectable avec Angular2/4/5/6.)
  2. Défis attendus: Quels défis peut-on rencontrer lors de la mise en œuvre d'un framework de plugins pour une Angular 2/4/5/6application?
  3. Stratégies de mise en œuvre: Quelles techniques ou stratégies spécifiques pourraient être employées pour implémenter un framework de plugins pour une Angular 2/4/5/6application?
  4. Meilleures pratiques: Quelles sont les meilleures pratiques pour implémenter un système de plugins pour une Angular 2/4/5/6application?
  5. Technologies alternatives: si un framework de plugins n'est pas pratique dans une Angular 2/4/5/6application, quelles technologies relativement équivalentes (par exemple React) pourraient convenir à une application Web moderne hautement réactive ?

En général, l'utilisation de Angular 2/4/5/6est très souhaitable car:

  • il est naturellement extrêmement rapide - de manière fulgurante.
  • il consomme très peu de bande passante (après le chargement initial)
  • il a une empreinte relativement petite (après AOTet tree shaking) - et cette empreinte continue de diminuer
  • il est hautement fonctionnel, et l'équipe et la communauté Angular poursuivent la croissance rapide de son écosystème
  • il fonctionne bien avec bon nombre des meilleures et dernières technologies Web telles que TypeScriptetObservables
  • Angular 5 prend désormais en charge les techniciens de service ( https://medium.com/@webmaxru/a-new-angular-service-worker-creating-automatic-progressive-web-apps-part-1-theory-37d7d7647cc7 )
  • étant soutenu par Google, il est susceptible d'être soutenu et amélioré dans le futur

J'aimerais beaucoup l'utiliser Angular 2/4/5/6pour mon projet actuel. Si je peux utiliser Angular 2/4/5/6, j'utiliserai également Angular-CLIet probablement Angular Universal(pour le rendu côté serveur.)

Voici mes réflexions, jusqu'à présent, concernant les questions ci-dessus. Veuillez examiner et fournir vos commentaires et éclaircissements.

  • Angular 2/4/5/6Les applications consomment des packages - mais ce n'est pas nécessairement la même chose que d'autoriser des plugins dans une application. Un plugin dans d'autres systèmes (par exemple Drupal) peut être essentiellement ajouté en déposant le dossier plugin dans un répertoire de modules commun où il est automatiquement "récupéré" par le système. Dans Angular 2/4/5/6, un package (comme un plugin pourrait l'être) est généralement installé via npm, ajouté au package.json, puis importé manuellement dans l'application - comme dans app.module. C'est beaucoup plus compliqué que la Drupalméthode de suppression d'un dossier et de détection automatique du paquet par le système. Plus il est compliqué d'installer un plugin, moins les gens seront susceptibles de les utiliser. Ce serait bien mieux s'il y avait un moyen pourAngular 2/4/5/6pour détecter et installer automatiquement les plugins. Je suis très intéressé de trouver une méthode qui permette aux non-développeurs d'installer l' Angular 2/4/5/6application et d'installer les plugins choisis sans avoir à comprendre toute l'architecture de l'application.

  • En général, l'un des avantages de fournir une architecture enfichable est qu'il est très facile pour les développeurs tiers d'étendre les fonctionnalités du système. De toute évidence, ces développeurs ne seront pas familiarisés avec toutes les subtilités du code de l'application à laquelle ils se connectent. Une fois les plugins développés, d'autres utilisateurs encore moins techniques peuvent simplement installer l'application et les plugins sélectionnés. Cependant, Angular 2/4/5/6est relativement compliqué et a une courbe d'apprentissage très longue. Pour d' autres choses compliquent, la plupart production des Angular 2/4/5/6applications utilisent aussi Angular-CLI, Angular Universalet WebPack. Quelqu'un qui implémente un plugin devrait probablement avoir au moins quelques connaissances de base sur la façon dont tous ces éléments s'emboîtent - ainsi qu'une solide connaissance pratique deTypeScriptet une familiarité raisonnable avec NodeJS. Les exigences en matière de connaissances sont-elles si extrêmes qu'aucun tiers ne voudrait jamais développer un plugin?

  • La plupart des plugins auront probablement un composant côté serveur (par exemple pour stocker / récupérer des données liées au plugin) ainsi qu'une sortie côté client. Angular 2/4/5décourage spécifiquement (et fortement) les développeurs d'injecter leurs propres modèles lors de l'exécution - car cela pose un risque sérieux pour la sécurité. Afin de gérer de nombreux types de sortie qu'un plugin peut accueillir (par exemple, l'affichage d'un graphique), il apparaît que permettre aux utilisateurs de créer du contenu qui est injecté dans le flux de réponse, sous une forme une autre, est probablement nécessaire. Je me demande comment il pourrait être possible de répondre à ce besoin sans déchiqueter au sens figuré Angular 2/4/5/6les mécanismes de sécurité.

  • La plupart des Angular 2/4/5/6applications de production sont précompilées à l'aide de la compilation Ahead of Time( AOT). (Probablement tous devraient l'être.) Je ne sais pas comment des plugins pourraient être ajoutés (ou intégrés à) des applications précompilées. Le meilleur scénario impliquerait de compiler les plugins séparément de l'application principale. Cependant, je ne sais pas comment faire fonctionner cela. Une solution de secours pourrait être de recompiler l'application entière avec les plugins inclus, mais cela complique un peu les choses pour un utilisateur administratif qui souhaite simplement installer l'application (sur son propre serveur) avec les plugins sélectionnés.

  • Dans une Angular 2/4/5/6application, en particulier une application pré-compilée, un seul morceau de code errant ou en conflit peut casser toute l'application. Angular 2/4/5/6les applications ne sont pas toujours les plus faciles à déboguer. L'application de plugins mal conduits peut entraîner des expériences très désagréables. Je ne suis actuellement pas au courant d'un mécanisme pour gérer gracieusement les plugins mal conduits.

Anthony Gatlin
la source
1
À mon avis, un module angular 2 est un plugin. @ angular / router, @ angular / forms, @ angular / http, @ angular / material, ce sont des 'plugins' d'angular, nous pouvons voir comment ils font des 'plugins'.
Timathon
8
@Timathon, malheureusement, ce ne sont pas les mêmes. Les systèmes de plugins permettent d'étendre une application sans modification du code de l'application principale. L'utilisation de @ angular / router, @ angular / forms, etc. oblige l'utilisateur à modifier l'application. Ce sont vraiment des bibliothèques par opposition aux plugins. Je suis vraiment plus intéressé à permettre aux utilisateurs administratifs non développeurs de sélectionner et d'utiliser les plugins qui les intéressent le plus sans avoir à connaître les détails internes de l'application.
Anthony Gatlin
1
Avez-vous obtenu quelque chose avec ça? Je suis intéressé à essayer quelque chose de similaire. La façon dont Angular 2 est construit (autour des modules) Je pensais qu'une architecture de type plugin lui conviendrait très bien mais cela ne semble pas être d'exemples, etc.
Joe
2
@Joe, je n'ai toujours pas de bonne solution à ce problème. J'ai pensé la même chose que toi.
Anthony Gatlin
2
J'ai créé un référentiel sur github avec une solution qui pourrait aider. Il utilise les bibliothèques Angular 6 et 1 applications de base qui chargent paresseusement les bibliothèques intégrées UMD; github.com/lmeijdam/angular-umd-dynamic-example Si vous avez des suggestions, n'hésitez pas à les ajouter!
Lars Meijdam

Réponses:

17

J'ai créé un référentiel sur github avec une solution qui pourrait aider. Il utilise les bibliothèques Angular 6 et 1 applications de base qui chargent paresseusement les bibliothèques intégrées UMD; https://github.com/lmeijdam/angular-umd-dynamic-example

Si vous avez des suggestions, n'hésitez pas à les ajouter!

Lars Meijdam
la source
2
Comme mentionné dans un autre commentaire, j'ai dû rendre le référentiel privé en raison de la politique de l'entreprise. Je le remettrai en ligne plus tard au fur et à mesure des discussions
Lars Meijdam
J'adorerais voir votre solution s'il vous plaît.
Subhan Ahmed
@Subhan, je suis actuellement en train de réécrire le référentiel avant de le remettre sur GH. Donnez-moi un peu plus de temps. Sinon, vous pouvez également me contacter directement! : D
Lars Meijdam
@ lars-meijdam: nous attendrons encore beaucoup: D ... Moi aussi très intéressé. Merci d'avance
aguetat
17

🛠️ Démo Github architecture-plugin angulaire

Peut-être qu'Ivy peut changer quelque chose, mais pour le moment, j'utilise la solution qui utilise Angular CLI Custom Builder et répond aux exigences suivantes:

  • AOT
  • éviter le code en double (packages comme @ angular / core {common, forms, router}, rxjs, tslib)
  • utiliser la bibliothèque partagée dans tous les plugins mais NE PAS EXPÉDIER les usines générées à partir de cette bibliothèque partagée dans chaque plugin mais plutôt réutiliser le code de la bibliothèque et les usines
  • le même niveau d'optimisation que nous offre Angular CLI
  • pour importer les modules externes, nous avons juste besoin de savoir une seule chose: leur chemin de fichier bundle
  • notre code doit reconnaître le module et placer le plugin dans la page
  • prise en charge du rendu côté serveur
  • charger le module uniquement en cas de besoin

L'utilisation est simple comme:

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

Plus à ce sujet dans mon article:

yurzui
la source
Excellent exemple! Une question. Comment puis-je passer OAuthTokenau moment de l'exécution au service Bibliothèque à partir de notre application principale?
yogen darji le
@yurzui pouvons-nous utiliser la même approche si nous avons plusieurs applications angulaires et que nous utilisons toute leur distribution au lieu de créer des modules comme vous avez fait le plugin 1 et le plugin 2?
Momin Shahzad
Pourriez-vous revenir sur cet exemple et le rendre compatible avec Ivy dans un proche avenir? Si vous le souhaitez, veuillez ajouter un exemple de service partagé et partagé InjectionTokenqui sera fourni dans l'AppModule et injecté dans d'autres plugins. Merci!
Jyrkka
11

Je viens de publier un nouveau chapitre pour mon livre " Developing with Angular " qui aborde le sujet des plugins dans Angular 2+ et devrait être d'un grand intérêt pour les personnes qui essaient de créer des plugins externes.

Points clés:

  • Plugins
  • Création de composants basés sur des noms de chaînes
  • Chargement de la configuration à partir de sources externes
  • Changement dynamique des itinéraires d'application
  • Plugins externes
  • Créer des bibliothèques de plugins
  • Chargement des plugins dans l'application
  • Routes dynamiques avec contenu de plugin

Le livre est gratuit et a un modèle «payez ce que vous voulez». N'hésitez pas à en prendre une copie et espérons que cela vous aidera.

Denys Vuika
la source
Comment puis-je remplacer un sous-composant par l'architecture de votre plugin illustrée dans le livre? Je vais remplacer le modèle ou peut-être ajouterai-je une propriété d'entrée ecc ... En même temps, j'ai besoin de savoir s'il existe un moyen de remplacer / étendre un service fourni.
Matteo Calò
1
@Denis Vuyka, Le livre a fière allure mais il lui manque la partie cruciale - le support de la compilation AoT.
Sergey Sokolov
7

Exemple d'application avec un système de plugins fonctionnel (merci à Gijs pour avoir fondé le dépôt github!) Https://github.com/PacktPublishing/Mastering-Angular-2-Components/tree/master/angular-2-components-chapter-10 based sur l'eBook Mastering Angular 2 Components

  • architecture de plugin pour étendre les composants de base de l'application
  • système de plugins de fichiers (pour simplement ajouter des répertoires / fichiers de plugins sans modifier les fichiers de configuration de base ou la nécessité de recompiler votre application!)
  • charger et utiliser dynamiquement des plugins
  • construire un gestionnaire de plugins rudimentaire pour activer / désactiver les plugins à la volée

Salutations, Niklas

Niklas Teich
la source
2
Vous ne pouvez pas voir un exemple de code à partir de ce lien, pouvez-vous publier un code Pen ou JSFiddle?
Sean Chase
4
J'ai lu le livre, mais la partie plugin est obsolète. Il utilise JS et SystemJS simples, tandis qu'Angular vise Typescript et Webpack. En utilisant Webpack et Typescript cela ne semble pas réalisable, j'ai posté une question au cas où vous auriez trouvé des solutions. Voici le lien
Luigi Dallavalle
Cela devrait aider: github.com/mgechev/angular-seed/issues/…
Guillaume
quelqu'un peut-il confirmer si ci-dessus fonctionne? Et si nous ne voulons pas utiliser systemjs
django
5

Ce que vous recherchez, c'est le chargement de module paresseux. En voici un exemple: 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;
    }
  }
}

Meilleur ... Tom

Tom I
la source
17
Merci d'avoir pris le temps de répondre à ma question. Je connais les modules chargés paresseusement, mais ce ne sont pas tout à fait ce que je recherche. Les modules chargés différés doivent toujours être connus au moment de la conception. Je cherche à pouvoir ajouter des modules et des fonctionnalités réels qui n'étaient pas connus ou envisagés lors de la création de l'application d'origine. (Ce que je recherche, c'est quelque chose d'un peu plus dynamique.) Certes, ces composants utiliseraient (une certaine forme de) chargement paresseux, mais ce n'est qu'une petite pièce du puzzle. Merci encore d'avoir partagé cette réponse.
Anthony Gatlin
1
Je conviens que cela ne répond pas à la question. Le chargement paresseux n'aide pas avec l'architecture des plugins car ils sont requis au moment de la conception. Il ne télécharge / ne transfère tout simplement pas les données au client jusqu'à ce que cela soit nécessaire.
Joe
Et si votre application connaissait tous les modules d'extension disponibles au moment de la compilation. Au moment où vous ajoutez un nouveau module à la plateforme, il doit être recompilé avec ce module. Juste une idée ... Je ne suis pas sûr que cela augmentera considérablement la taille des fichiers JS, je ne sais pas si la fonction de chargement paresseux placera ce module dans un fichier séparé, puis le chargera paresseusement, je partage juste mon idée ...
Vladimir Prudnikov
@VladimirPrudnikov, si une application pouvait connaître tous les plugins au moment de la compilation, ce serait fantastique. Cependant, l'idée est de pouvoir ajouter des plugins éventuellement après la compilation de l'application. Cela permettrait un branchement vraiment dynamique des modules. Cependant, cela exigerait que les modules soient également pré-compilés au moment de leur déploiement - et je ne sais pas comment cela fonctionnerait. Je ne sais pas non plus comment garder la version des modules du plugin compatible avec Angular.
Anthony Gatlin
2

J'ai fait un hack pour charger et compiler d'autres modules au moment du bootstrap, mais je n'ai pas résolu le problème des dépendances cycliques

 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));

puis dans AppModule, ajoutez ceci:

{
        provide: APP_INITIALIZER,
        useFactory: AppsLoaderFactory,
        deps: [AppsLoader],
        multi: true
},
José Luis Berrocal
la source
2

Je cherchais également un système de plugins en angulaire 2/4 pour développer un environnement RAD pour une application d'entreprise au travail. Après quelques recherches, j'ai décidé d'implémenter une collection de composants pseudo-angulaires stockés dans la base de données (mais pourraient être dans le système de fichiers).

Les composants stockés dans la base de données de la base de données sont basés sur ng-dynamic et l'implémentation du composant principal est similaire à ceci:

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();
                }

            });

        });

    }

Le code javascript externe est similaire aux composants angulaires:

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'; 

};

Et les modèles des composants sont comme des modèles angulaires:

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

Et pourrait être imbriqué aussi:

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

Bien que ce ne soit pas parfait, les développeurs des composants personnalisés ont un cadre similaire à celui d'angular2 / 4.

zarpilla
la source
2

Cela peut être fait "manuellement". Puisque webpack ne sait rien des modules externes (plug-ins), il ne peut pas les inclure dans le (s) bundle (s). Donc, ce que j'ai fait, c'est regarder le code généré par webpack et j'ai trouvé ces pies de code dans main.bundle.js:

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

Examinons ce que contient ce tableau:

  1. "./dashboard/dashboard.module" - il s'agit de l'URL de routage du module que nous voulons charger paresseux par exemple: {chemin: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule'}
  2. "../../../../../src/app/dashboard/dashboard.module.ts" - c'est le point d'entrée (constructeur) prend de
  3. "dashboard.module" - nom de fichier réel sans chunk.js (par exemple: dashboard.module.chunk.js )

Donc, en théorie, si vous ajoutez une entrée à la propriété map, configurez votre routage et suivez le modèle, vous pouvez avoir un système de plug-in. Le défi consiste maintenant à ajouter ou supprimer des entrées de cette propriété de carte. Évidemment, cela ne peut pas être fait à partir de code angulaire, cela devrait être fait pour un outil externe.

Niki Uzun
la source
2

J'ai essayé d'implémenter une architecture de plugin utilisant ABP, Angular et ASP.NET Core: https://github.com/chanjunweimy/abp_plugin_with_ui

En gros, j'ai développé des plugins angulaires en utilisant différentes applications angulaires, puis je les ajoute dynamiquement.

Plus d'informations sur comment j'y parviens:

J'ai 2 applications angular-cli, 1 est l'application angular cli principale et une autre est l'application angular cli plugin. Le problème auquel nous sommes confrontés dans l'approche d'architecture de plugin Angular-cli est de savoir comment nous les intégrons.

À l'heure actuelle, ce que j'ai fait, c'est d'exécuter ng-build sur les deux applications et de les mettre dans un dossier «wwwroot», qui est ensuite hébergé sur un serveur ASP.NET core 2.0. Un référentiel plus simple qui montre cette idée est Angular Multiple App: https://github.com/chanjunweimy/angular-multiple-app

abp_plugin_with_ui est un référentiel qui travaille sur le développement d'un plugin qui contient à la fois le backend et Angular cli. Pour le backend, j'ai utilisé le framework aspnetboilerplate, dont le frontend est développé à l'aide de plusieurs applications angular-cli.

Pour que l'application principale soit intégrée à l'application du plugin, nous devons exécuter "ng-build" sur les deux applications (notez que nous devons également changer en href de l'application du plugin), puis nous déplaçons le contenu construit du plugin angular cli, vers le dossier principal de l'application "wwwroot". Après avoir réalisé tout cela, nous pouvons alors exécuter "dotnet run" pour servir l'application Web ASP.NET Core 2.0 pour héberger les fichiers statiques générés par "ng build".

Espérons que cela aide. Tout commentaire est le bienvenu! ^^

Junwei Chan
la source
J'essaie de suivre la documentation de votre plugin, mais je pense que la documentation saute quelques étapes. Je m'excuse si je l'ai mal lu. Le morceau «ajouter un plugin» n'est pas clair pour moi. J'ai suivi cette étape par étape, mais je ne vois pas vraiment de résultats. Que dois-je voir sur le port 4200 après avoir exécuté le Power Shell? Je ne vois pas de dossier Plugins dans /aspnet-core/src/Todo.MainProject.Web.Host/. J'ai exécuté le PowerShell et ce dossier n'a pas été créé. Toute aide appréciée. Je pense que votre approche est ce dont j'ai besoin, mais je suis un peu floue sur son fonctionnement.
Brian Kitt
D'accord. J'aurais dû le faire avant de poser la question. J'ai passé du temps à déboguer et j'ai trouvé mes réponses. # 1) Le PowerShell ne place pas le .zip là où il doit aller, je dois créer le dossier du plugin et déplacer le zip. # 2) Lorsque l'application angulaire démarre, elle appelle dynamiquement le chargeur et copie les plugins dans la racine Web. C'était en quelque sorte précisé, mais je comprends maintenant. # 3) Je dois utiliser l'url pour appeler le plugin, il n'apparaît nulle part. Je m'attendais à ce que ce soit sur le tableau de bord. Merci pour votre travail, c'est un morceau de code important.
Brian Kitt
2

Un peu hors sujet, mais les bibliothèques de composants d'interface utilisateur pourraient intéresser certains lecteurs, qui recherchent des plugins:
https://medium.com/@nikolasleblanc/building-an-angular-4-component-library-with-the -angulaire-cli-et-ng-packagr-53b2ade0701e

NativeScript a des plugins d'interface utilisateur intégrés:
https://docs.nativescript.org/plugins/building-plugins
Ces plugins ont besoin d'un wrapper angulaire:
https://docs.nativescript.org/plugins/angular-plugin

RaSor
la source
2

Je suis actuellement dans la même quête que vous, en train d'essayer de créer une version enfichable / themable d'Angular, et ce n'est pas un problème trivial.

J'ai en fait trouvé de bonnes solutions, en lisant le livre Developing with Angular du Genius Denys Vuyika , il explique dans le livre une assez bonne solution, il parle de plugins externes à la page 356 du livre et utilise Rollup.js pour réaliser le solution, il procède ensuite pour charger dynamiquement des plugins externes qui ont été précédemment créés en dehors de votre application.

Il existe également deux autres bibliothèques / projets qui vous aident à atteindre ce résultat . Extensions ng-packagr et Nx pour Agnular (de Nrwl) nous sommes en train de mettre en œuvre ce dernier, et je dirais que ce n'est pas aussi fluide que nous l'avions prévu, angular était simple pas construit pour cela, nous devons donc travailler autour d'une partie du noyau sur la façon dont Angular, et les ppl NX sont l'un des meilleurs.

Nous ne sommes qu'au début de notre projet Open Source, nous utilisons Django + Mongo + Angular, (nous appelons WebDjangular et l'une de nos approches possibles à cette réponse, c'est que Django devra écrire des fichiers de configuration JSON et construire le application chaque fois qu'un nouveau plugin ou thème est installé et activé.

Ce que nous avons déjà accompli, c'est qu'à partir de la base de données, nous pouvons utiliser des balises pour les composants comme sur le plugin, et le composant sera imprimé à l'écran! Encore une fois, le projet en est à ses tout débuts, nous basons un peu notre architecture sur Wordpress, et nous avons encore beaucoup de tests à faire pour réaliser notre rêve: D

J'espère que le livre peut vous aider, et en utilisant Rollup.js, je sais que vous serez en mesure de résoudre ce problème non trivial.

Paulo Peres Junior
la source