Implementing a plugin architecture / plugin system / pluggable framework in Angular 2, 4, 5, 6 Ask Question

Implementing a plugin architecture / plugin system / pluggable framework in Angular 2, 4, 5, 6 Ask Question

Update 5/24/2018: We are now +3 versions of Angular from my original post and still don't have a final workable solution. Lars Meijdam (@LarsMeijdam) has come up with an interesting approach which is certainly worth a look-see. (Due to proprietary issues, he had to temporarily remove the GitHub repository where he had originally posted his sample. However, you may message him directly if you would like a copy. Please see the comments below for more info.)

Recent architectural changes in Angular 6 do bring us closer to a solution. Additionally, Angular Elements (https://angular.io/guide/elements) provides some component functionality--though not quite what I originally described in this post.

If anyone from the amazing Angular team happens to come across this, please note that there seem to be many other people who are also very interested in this functionality. It might well be worth considering for the backlog.


I would like to implement a pluggable (plug-in) framework in an Angular 2, Angular 4, Angular 5, or Angular 6 application.

(My specific use case for developing this pluggable framework is that I need to develop a miniature content management system. For a number of reasons not necessarily elaborated here, Angular 2/4/5/6 is a near perfect fit for most of the needs of that system.)

By pluggable framework (or plug-in architecture), I specifically mean a system which allows third party developers to create or extend the functionality of a primary application through the use of pluggable components without having direct access to or knowledge of the primary application's source code or inner workings.

(That phrasing about "without having direct access to or knowledge of the application's source code or inner workings" is a core objective.)

Examples of pluggable frameworks include common content management systems like WordPress or Drupal.

The ideal situation (as with Drupal) would be to simple be able to place these pluggable components (or plug-ins) into a folder, have the application auto-detect or discover them, and have them just magically "work." Having this occur in some sort of hot-pluggable manner, meaning while the app was running, would be optimum.

I am currently trying to determine answers (with your help) to the following five questions.

  1. Practicality: Is a plugin framework for an Angular 2/4/5/6 application even practical? (Until now, I have not found any practical way to create a truly pluggable framework with Angular2/4/5/6.)
  2. Expected Challenges: What challenges might one encounter in implementing a plugin framework for an Angular 2/4/5/6 application?
  3. Implementation Strategies: What specific techniques or strategies could be employed for implementing a plugin framework for an Angular 2/4/5/6 application?
  4. Best Practices: What are the best practices for implementing a plugin system for an Angular 2/4/5/6 application?
  5. Alternative Technologies: Ifプラグインフレームワークはないアプリケーションで実用的なAngular 2/4/5/6もの比較的同等技術(例React)は、最新の高反応Webアプリケーション?

一般的に、 の使用はAngular 2/4/5/6以下の理由から非常に望ましいです。

  • それは当然ながら極めて高速です。驚くほどです。
  • 帯域幅の消費量は非常に少ない(初期ロード後)
  • フットプリントは比較的小さい(および後AOTtree shaking-そしてそのフットプリントは縮小し続けている
  • 機能性が高く、Angularチームとコミュニティはエコシステムの急速な成長を続けています。
  • などの多くの最新かつ最高のWebテクノロジーと連携しますTypeScriptObservables
  • Angular 5ではサービスワーカーがサポートされるようになりました(https://medium.com/@webmaxru/a-new-angular-service-worker-creating-automatic-progressive-web-apps-part-1-theory-37d7d7647cc7
  • によって支えられているためGoogle、将来にわたってサポートされ、強化される可能性が高い。

現在のプロジェクトでは をぜひ使用したいと思っていますAngular 2/4/5/6。 を使用できる場合は、おそらくAngular 2/4/5/6と も使用します(サーバー側レンダリング用)。Angular-CLIAngular Universal

上記の質問に関して、これまでのところ私の考えは次のとおりです。ぜひレビューして、フィードバックやご意見をお寄せください。

  • Angular 2/4/5/6アプリはパッケージを使用しますが、これは必ずしもアプリケーション内でプラグインを許可することと同じではありません。他のシステム (例Drupal) のプラグインは、基本的に、プラグイン フォルダを共通のモジュール ディレクトリにドロップすることで追加でき、そこでシステムによって自動的に「取得」されます。 ではAngular 2/4/5/6、パッケージ (プラグインなど) は通常 を介してインストールされnpm、 に追加されてpackage.jsonから、 のように手動でアプリにインポートされますapp.module。これは、フォルダをドロップしてシステムによってパッケージを自動的に検出する方法よりもはるかに複雑ですDrupalプラグインのインストールが複雑になるほど、ユーザーがプラグインを使用する可能性は低くなります。プラグインを自動的に検出してインストールする方法があれば、もっと良いでしょうAngular 2/4/5/6。開発者以外の人がAngular 2/4/5/6アプリケーションのアーキテクチャをすべて理解しなくても、アプリケーションをインストールし、選択したプラグインをインストールできる方法を見つけることに非常に興味があります。

  • Generally, one of the benefits of providing a pluggable architecture, is that it is very easy for 3rd party developers to extend the functionality of the system. Obviously, these developers will not be familiar with all of the intricacies of the code for the application they are plugging into. Once the plugins are developed, other even less technical users may simply install the application and any selected plugins. However, Angular 2/4/5/6 is relatively complicated and has a very lengthy learning curve. To further complicate things, most production Angular 2/4/5/6 applications also utilize Angular-CLI, Angular Universal, and WebPack. Someone who is implementing a plugin would probably have to have at least some basic knowledge of how all of these fit together--along with a strong working knowledge of TypeScript and a reasonable familiarity with NodeJS. Are the knowledge requirements so extreme that no third party would ever want to develop a plugin?

  • Most plugins will likely have some server side component (e.g. for storing/retrieving plugin related data) as well as some client-side output. Angular 2/4/5 specifically (and strongly) discourages developers from injecting their own templates at runtime--as this poses a serious security risk. In order to handle many types of output that a plugin may accommodate (e.g. display of a graph), it appears that allowing users to create content which is injected into the response stream, in one form another, is probably necessary. I wonder how it might be possible to accommodate this need without figuratively shredding Angular 2/4/5/6's security mechanisms.

  • Most production Angular 2/4/5/6 applications are pre-compiled using Ahead of Time (AOT) compilation. (Probably all should be.) I am uncertain how plugins might be added to (or integrated with) pre-compiled applications. The best scenario would involve compiling the plugins separately from the main application. However, I am uncertain how to make this work. A fallback might be to re-compile the entire application with any included plugins but that complicates things a bit for an administrative user who simply wants to install the application (on his own server) along with any selected plugins.

  • In an Angular 2/4/5/6 application, especially a pre-compiled one, a single piece of errant or conflicting code can break the entire application. Angular 2/4/5/6 applications are not always the easiest to debug. Application of ill-behaved plugins could result in very unpleasant experiences. I am currently unaware of a mechanism to gracefully handle ill-behaved plugins.

ベストアンサー1

Update

For Angular 11 I strongly recommend you to take a look at implementation with Webpack 5 Module Federation

�� https://github.com/alexzuza/angular-plugin-architecture-with-module-federation

Previos version

��️ Github demo angular-plugin-architecture

Ivy で何か変更できるかもしれませんが、当面は、Angular CLI カスタム ビルダーを使用し、次の要件を満たすソリューションを使用します。

  • オーストラリア
  • 重複コードを避ける(@angular/core{common,forms,router}、rxjs、tslib などのパッケージ)
  • すべてのプラグインで共有ライブラリを使用しますが、各プラグインでその共有ライブラリから生成されたファクトリを出荷するのではなく、ライブラリコードとファクトリを再利用します。
  • Angular CLIが提供するのと同じレベルの最適化
  • 外部モジュールをインポートするには、バンドルファイルのパスだけを知っておく必要があります。
  • コードはモジュールを認識し、プラグインをページに配置する必要があります
  • サーバーサイドレンダリングをサポート
  • 必要なときだけモジュールをロードする

使い方は簡単です:

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

これについては私の記事で詳しく説明しています:

おすすめ記事