Triển khai kiến ​​trúc plugin / hệ thống plugin / khung có thể cắm trong Angular 2, 4, 5, 6


133

Cập nhật 24/5/2018: Chúng tôi hiện là +3 phiên bản Angular từ bài đăng gốc của tôi và vẫn chưa có giải pháp khả thi cuối cùng. Lars Meijdam (@LarsMeijdam) đã đưa ra một cách tiếp cận thú vị mà chắc chắn đáng xem. (Do vấn đề độc quyền, anh ấy đã phải tạm thời xóa kho GitHub nơi anh ấy đã đăng mẫu ban đầu của mình. Tuy nhiên, bạn có thể nhắn tin trực tiếp cho anh ấy nếu bạn muốn có một bản sao. Vui lòng xem các bình luận bên dưới để biết thêm thông tin.)

Những thay đổi kiến ​​trúc gần đây trong Angular 6 đã đưa chúng ta đến gần hơn với một giải pháp. Ngoài ra, các yếu tố góc ( https://angular.io/guide/elements ) cung cấp một số chức năng thành phần - mặc dù không hoàn toàn như những gì tôi mô tả ban đầu trong bài viết này.

Nếu bất cứ ai trong nhóm Angular tuyệt vời tình cờ bắt gặp điều này, xin lưu ý rằng dường như có nhiều người khác cũng rất quan tâm đến chức năng này. Nó có thể là giá trị xem xét cho các tồn đọng.


Tôi muốn thực hiện một (plug-in) khuôn khổ cắm trong một Angular 2, Angular 4, Angular 5, hoặc Angular 6ứng dụng.

(Trường hợp sử dụng cụ thể của tôi để phát triển khung có thể cắm này là tôi cần phát triển hệ thống quản lý nội dung thu nhỏ. Vì một số lý do không nhất thiết phải được xây dựng ở đây, Angular 2/4/5/6là một sự phù hợp gần như hoàn hảo cho hầu hết các nhu cầu của hệ thống đó.)

Theo khung có thể cắm (hoặc kiến ​​trúc trình cắm), tôi đặc biệt có nghĩa là một hệ thống cho phép các nhà phát triển bên thứ ba tạo hoặc mở rộng chức năng của ứng dụng chính thông qua việc sử dụng các thành phần có thể cắm được mà không cần truy cập trực tiếp hoặc hiểu biết về mã nguồn của ứng dụng chính hoặc hoạt động bên trong .

(Đó là cụm từ về " không có quyền truy cập trực tiếp hoặc kiến ​​thức về mã nguồn hoặc hoạt động bên trong của ứng dụng " là mục tiêu cốt lõi.)

Ví dụ về các khung có thể cắm bao gồm các hệ thống quản lý nội dung phổ biến như WordPress hoặc Drupal.

Tình huống lý tưởng (như với Drupal) là đơn giản để có thể đặt các thành phần có thể cắm (hoặc plugin) này vào một thư mục, để ứng dụng tự động phát hiện hoặc khám phá chúng và giúp chúng hoạt động một cách kỳ diệu. Có điều này xảy ra theo một cách thức nào đó có thể cắm nóng, có nghĩa là trong khi ứng dụng đang chạy, sẽ là tối ưu.

Tôi hiện đang cố gắng xác định câu trả lời ( với sự giúp đỡ của bạn ) cho năm câu hỏi sau đây.

  1. Tính thực tiễn: Là một khung plugin cho một Angular 2/4/5/6ứng dụng thậm chí là thực tế? (Cho đến bây giờ, tôi chưa tìm thấy bất kỳ cách thực tế nào để tạo ra một khung thực sự có thể cắm được Angular2/4/5/6.)
  2. Những thách thức dự kiến: Những thách thức nào người ta có thể gặp phải khi triển khai khung plugin cho một Angular 2/4/5/6ứng dụng?
  3. Chiến lược triển khai: Những kỹ thuật hoặc chiến lược cụ thể nào có thể được sử dụng để triển khai khung plugin cho Angular 2/4/5/6ứng dụng?
  4. Thực tiễn tốt nhất: Thực tiễn tốt nhất để triển khai hệ thống plugin cho Angular 2/4/5/6ứng dụng là gì?
  5. Các công nghệ thay thế: Nếu một khung plugin không thực tế trong một Angular 2/4/5/6ứng dụng, công nghệ tương đối nào (ví dụ React) có thể phù hợp với một ứng dụng Web có tính phản ứng cao hiện đại ?

Nói chung, việc sử dụng Angular 2/4/5/6là rất mong muốn bởi vì:

  • nó tự nhiên cực kỳ nhanh - rực rỡ như vậy.
  • nó tiêu thụ rất ít băng thông (sau khi tải ban đầu)
  • nó có một dấu chân tương đối nhỏ (sau AOTtree shaking ) - và dấu chân đó tiếp tục co lại
  • nó có tính ứng dụng cao, và nhóm Angular và cộng đồng đang tiếp tục phát triển nhanh chóng hệ sinh thái của nó
  • nó chơi tốt với nhiều công nghệ Web mới nhất và tốt nhất như TypeScriptObservables
  • Angular 5 hiện hỗ trợ nhân viên dịch vụ ( https://medium.com/@webmaxru/a-new-angular-service-worker-creating-automatic-proTHERive-web-apps-part-1-theory-37d7d7647cc7 )
  • được hỗ trợ bởi Google, nó có khả năng sẽ được hỗ trợ và nâng cao trong tương lai

Tôi rất muốn sử dụng Angular 2/4/5/6cho dự án hiện tại của tôi. Nếu tôi có thể sử dụng Angular 2/4/5/6, tôi cũng sẽ sử dụng Angular-CLIvà có lẽ Angular Universal(để kết xuất phía máy chủ.)

Dưới đây là những suy nghĩ của tôi, cho đến nay, liên quan đến các câu hỏi ở trên. Vui lòng xem xét và cung cấp thông tin phản hồi và giác ngộ của bạn.

  • Angular 2/4/5/6các ứng dụng tiêu thụ các gói - nhưng điều này không nhất thiết giống như cho phép các plugin trong một ứng dụng. Một plugin trong các hệ thống khác (ví dụ Drupal) về cơ bản có thể được thêm bằng cách thả thư mục plugin vào thư mục mô-đun chung nơi hệ thống tự động "nhặt". Trong Angular 2/4/5/6, một gói (như một plugin có thể) thường được cài đặt qua npm, thêm vào package.json, sau đó nhập thủ công vào ứng dụng - như trong app.module. Điều này phức tạp hơn nhiều so với Drupalphương pháp bỏ thư mục và hệ thống tự động phát hiện gói. Việc cài đặt một plugin càng phức tạp thì càng ít khả năng mọi người sẽ sử dụng chúng.Sẽ tốt hơn nhiều nếu có một cách choAngular 2/4/5/6để tự động phát hiện và cài đặt plugin. Tôi rất muốn tìm một phương pháp cho phép những người không phải là nhà phát triển cài đặt Angular 2/4/5/6ứng dụng và cài đặt bất kỳ plugin nào được chọn mà không cần phải hiểu tất cả kiến ​​trúc của ứng dụng.

  • Nói chung, một trong những lợi ích của việc cung cấp kiến ​​trúc có thể cắm được là rất dễ dàng cho các nhà phát triển bên thứ 3 mở rộng chức năng của hệ thống. Rõ ràng, các nhà phát triển này sẽ không quen thuộc với tất cả những điều phức tạp của mã cho ứng dụng mà họ đang cắm vào. Khi các plugin được phát triển, những người dùng ít kỹ thuật khác thậm chí có thể chỉ cần cài đặt ứng dụng và mọi plugin đã chọn. Tuy nhiên, Angular 2/4/5/6tương đối phức tạp và có thời gian học tập rất dài. Để điều phức tạp hơn nữa, hầu hết các sản xuất Angular 2/4/5/6các ứng dụng cũng sử dụng Angular-CLI, Angular UniversalWebPack. Ai đó đang thực hiện một plugin có thể phải có ít nhất một số kiến ​​thức cơ bản về cách tất cả các plugin này khớp với nhau - cùng với kiến ​​thức làm việc mạnh mẽ vềTypeScript và một sự quen thuộc hợp lý với NodeJS. Các yêu cầu về kiến ​​thức có cực đoan đến mức không bên thứ ba nào muốn phát triển plugin không?

  • Hầu hết các plugin có thể sẽ có một số thành phần phía máy chủ (ví dụ: để lưu trữ / truy xuất dữ liệu liên quan đến plugin) cũng như một số đầu ra phía máy khách. Angular 2/4/5cụ thể (và mạnh mẽ) không khuyến khích các nhà phát triển tiêm các mẫu riêng của họ khi chạy - vì điều này gây rủi ro bảo mật nghiêm trọng. Để xử lý nhiều loại đầu ra mà plugin có thể chứa (ví dụ: hiển thị biểu đồ), có vẻ như cho phép người dùng tạo nội dung được đưa vào luồng phản hồi, dưới dạng khác, có thể là cần thiết. Tôi tự hỏi làm thế nào có thể đáp ứng nhu cầu này mà không cần cắt xén theo Angular 2/4/5/6cơ chế bảo mật.

  • Hầu hết các Angular 2/4/5/6ứng dụng sản xuất được biên dịch trước bằng cách sử dụng Ahead of Time( AOT) biên dịch. (Có lẽ tất cả nên như vậy.) Tôi không chắc chắn làm thế nào các plugin có thể được thêm vào (hoặc tích hợp với) các ứng dụng được biên dịch trước. Kịch bản tốt nhất sẽ liên quan đến việc biên dịch các plugin riêng biệt với ứng dụng chính. Tuy nhiên, tôi không chắc làm thế nào để làm cho công việc này. Một dự phòng có thể là biên dịch lại toàn bộ ứng dụng với bất kỳ plugin nào đi kèm nhưng điều đó làm phức tạp mọi thứ một chút cho người dùng quản trị, những người chỉ muốn cài đặt ứng dụng (trên máy chủ của chính mình) cùng với bất kỳ plugin nào được chọn.

  • Trong một Angular 2/4/5/6ứng dụng, đặc biệt là một ứng dụng được biên dịch sẵn, một đoạn mã sai lầm hoặc xung đột có thể phá vỡ toàn bộ ứng dụng. Angular 2/4/5/6các ứng dụng không phải lúc nào cũng dễ gỡ lỗi nhất. Áp dụng các plugin hành vi xấu có thể dẫn đến trải nghiệm rất khó chịu. Tôi hiện không biết về một cơ chế để xử lý các plugin có hành vi xấu.


1
Theo ý kiến ​​của tôi, một mô-đun 2 góc là một plugin. @ angular / bộ định tuyến, @ angular / Forms, @ angular / http, @ angular / liệu, đây là những 'plugin' từ góc, chúng ta có thể kiểm tra cách chúng tạo ra 'plugin'.
Timathon

8
@Timathon, thật không may, chúng không giống nhau. Các hệ thống plugin cho phép một ứng dụng được mở rộng mà không cần sửa đổi mã ứng dụng cốt lõi. Sử dụng @ angular / bộ định tuyến, @ angular / Forms, v.v ... yêu cầu người dùng sửa đổi ứng dụng. Đó thực sự là những thư viện trái ngược với plugin. Tôi thực sự quan tâm hơn đến việc cho phép người dùng quản trị không phải là nhà phát triển lựa chọn và sử dụng các plugin thú vị nhất đối với họ mà không cần phải biết các chi tiết nội bộ của ứng dụng.
Anthony Gatlin

1
Bạn đã nhận được bất cứ nơi nào với điều này? Tôi thích thử một cái gì đó tương tự. Cách Angular 2 được xây dựng (xung quanh các Mô-đun) Tôi nghĩ rằng một kiến ​​trúc kiểu plugin sẽ rất phù hợp với nó nhưng dường như không có bất kỳ ví dụ nào, v.v.
Joe

2
@Joe, tôi vẫn chưa có giải pháp tốt cho vấn đề này. Tôi cũng nghĩ giống như bạn.
Anthony Gatlin

2
Tôi đã tạo một kho lưu trữ trên github với một giải pháp có thể giúp ích. Nó sử dụng các thư viện Angular 6 và 1 ứng dụng cơ bản tải lên các thư viện đi kèm UMD một cách lười biếng; github.com/lmeijdam/angular-umd-dynamic-example Nếu bạn có bất kỳ đề xuất nào, xin vui lòng thêm!
Lars Meijdam

Câu trả lời:


17

Tôi đã tạo một kho lưu trữ trên github với một giải pháp có thể giúp ích. Nó sử dụng các thư viện Angular 6 và 1 ứng dụng cơ bản tải lên các thư viện đi kèm UMD một cách lười biếng; https://github.com/lmeijdam/angular-umd-dynamic-example

Nếu bạn có bất kỳ đề nghị, xin vui lòng thêm!


2
Như đã đề cập trong một bình luận khác, tôi phải đặt kho lưu trữ ở chế độ riêng tư do chính sách của công ty .. Tôi sẽ đưa nó trở lại trực tuyến sau khi các cuộc thảo luận đang diễn ra
Lars Meijdam

Rất muốn xem giải pháp của bạn xin vui lòng.
Subhan Ahmed

@Subhan, tôi hiện đang bận viết lại kho lưu trữ trước khi đặt lại GH. Hãy cho tôi thêm một chút thời gian. Nếu không bạn cũng có thể liên hệ trực tiếp với tôi! : D
Lars Meijdam

@ lars-meijdam: chúng tôi vẫn sẽ chờ đợi rất nhiều: D ... Tôi cũng rất thích thú. Cảm ơn bạn trước
aguetat

17

Github demo angular-plugin-architecture

Có thể Ivy có thể thay đổi một cái gì đó nhưng hiện tại tôi đang sử dụng giải pháp sử dụng Angular CLI Custom Builder và đáp ứng các yêu cầu sau:

  • AOT
  • tránh mã trùng lặp (các gói như @ angular / core {common, Forms, router}, rxjs, tslib)
  • sử dụng thư viện dùng chung trong tất cả các plugin nhưng KHÔNG SHIP tạo các nhà máy từ thư viện dùng chung đó trong mỗi plugin mà sử dụng lại mã thư viện và nhà máy
  • cùng mức độ tối ưu hóa mà Angular CLI mang lại cho chúng ta
  • để nhập các mô-đun bên ngoài, chúng ta chỉ cần biết một điều: đường dẫn tệp bó của chúng
  • mã của chúng tôi sẽ nhận ra mô-đun và đặt plugin vào trang
  • hỗ trợ kết xuất phía máy chủ
  • chỉ tải mô-đun khi cần

Cách sử dụng rất đơn giản như:

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

Thêm về điều này trong bài viết của tôi:


Ví dụ tuyệt vời! Một câu hỏi. Làm cách nào tôi có thể chuyển OAuthTokenkhi chạy đến dịch vụ Thư viện từ ứng dụng chính của chúng tôi?
yogen darji

@yurzui chúng ta có thể sử dụng cùng một cách tiếp cận nếu chúng ta có nhiều ứng dụng góc cạnh và chúng ta sử dụng toàn bộ phân phối của chúng thay vì tạo một mô-đun như bạn đã làm plugin 1 và plugin 2?
Momin Shahzad

Bạn có thể xem lại ví dụ này và làm cho nó tương thích với Ivy trong tương lai gần không? Nếu bạn muốn, vui lòng thêm một ví dụ về dịch vụ chia sẻ và chia sẻ InjectionTokensẽ được cung cấp trong AppModule và được thêm vào các plugin khác. Cảm ơn!
Jyrkka

11

Tôi vừa xuất bản một chương mới cho cuốn sách " Phát triển với góc " của mình đề cập đến chủ đề bổ trợ trong Angular 2+ và rất đáng quan tâm đối với những người đang cố gắng xây dựng các plugin bên ngoài.

Những điểm chính:

  • bổ sung
  • Xây dựng các thành phần dựa trên tên chuỗi
  • Đang tải cấu hình từ các nguồn bên ngoài
  • Thay đổi động các tuyến ứng dụng
  • Plugin ngoài
  • Tạo thư viện plugin
  • Đang tải plugin vào ứng dụng
  • Các tuyến động với nội dung plugin

Cuốn sách là miễn phí để có được, và có mô hình "trả những gì bạn muốn". Hãy lấy một bản sao và hy vọng rằng sẽ giúp.


Làm cách nào tôi có thể thay thế một thành phần phụ bằng kiến ​​trúc plugin của bạn được minh họa trong sách? Tôi sẽ thay thế mẫu hoặc có thể tôi sẽ thêm một thuộc tính đầu vào ecc ... Đồng thời tôi cần biết nếu tồn tại một cách để ghi đè / mở rộng một dịch vụ được cung cấp.
Matteo Calò

1
@Denis Vuyka, Cuốn sách có vẻ hay nhưng nó thiếu phần cốt yếu - hỗ trợ biên soạn AoT.
Sergei Sokolov

7

Ứng dụng ví dụ với một hệ thống plugin làm việc (nhờ Gijs cho thành lập repo github!) Https://github.com/PacktPublishing/Mastering-Angular-2-Components/tree/master/angular-2-components-chapter-10 dựa trên Sách điện tử Làm chủ các thành phần góc 2

  • kiến trúc plugin để mở rộng các thành phần ứng dụng cốt lõi
  • hệ thống plugin tệp (chỉ cần thêm thư mục / tệp plugin mà không cần chỉnh sửa bất kỳ tệp cấu hình lõi nào hoặc cần phải biên dịch lại ứng dụng của bạn!)
  • tải và tự động sử dụng plugin
  • xây dựng trình quản lý plugin thô sơ để kích hoạt / tắt các plugin đang hoạt động

Chúc mừng, Niklas


2
Không thể xem mã ví dụ từ liên kết đó, bạn có thể đăng Mã Pen hoặc JSFiddle không?
Sean Chase


4
Tôi đọc cuốn sách, nhưng phần plugin đã hết hạn. Nó sử dụng JS và SystemJS đơn giản, trong khi Angular đang hướng tới Typecript và Webpack. Sử dụng Webpack và Typecript dường như không thể đạt được, tôi đã đăng một câu hỏi trong trường hợp bạn tìm thấy bất kỳ giải pháp nào. Đây là đường dẫn
Luigi Dallavalle


ai đó có thể xác nhận nếu ở trên làm việc? Điều gì xảy ra nếu chúng ta không muốn sử dụng systemjs
django

5

Những gì bạn đang tìm kiếm là tải mô-đun lười biếng. Dưới đây là một ví dụ về nó: 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;
    }
  }
}

Tốt nhất ... Tom


17
Cảm ơn bạn đã dành thời gian để trả lời câu hỏi của tôi. Tôi quen thuộc với các mô-đun tải lười biếng, nhưng đây không phải là những gì tôi đang tìm kiếm. Các mô-đun tải lười biếng vẫn phải được biết đến tại thời điểm thiết kế. Tôi đang tìm cách để có thể thêm các mô-đun và chức năng thực tế mà không biết hoặc hình dung khi ứng dụng gốc được xây dựng. (Thứ tôi đang tìm kiếm là thứ gì đó năng động hơn một chút.) Chắc chắn những thành phần đó sẽ sử dụng (một số dạng) lười tải nhưng nó chỉ là một mảnh nhỏ của câu đố. Cảm ơn bạn một lần nữa vì đã chia sẻ câu trả lời này.
Anthony Gatlin

1
Tôi đồng ý điều này không trả lời câu hỏi. Tải lười biếng không giúp ích gì với kiến ​​trúc plugin vì chúng được yêu cầu tại thời điểm thiết kế. Nó chỉ đơn giản là không tải / chuyển dữ liệu cho khách hàng cho đến khi được yêu cầu.
Joe

Điều gì sẽ xảy ra nếu ứng dụng của bạn sẽ biết về tất cả các mô-đun trình cắm có sẵn tại thời điểm biên dịch. Tại thời điểm bạn thêm một mô-đun mới vào nền tảng, nó phải được biên dịch lại với mô-đun này. Chỉ là một ý tưởng ... Không chắc chắn tôi sẽ tăng kích thước tệp JS một cách đáng kể, không chắc tính năng tải lười biếng sẽ đưa mô-đun đó vào một tệp riêng biệt và sau đó lười tải nó, tôi chỉ chia sẻ ý tưởng của mình ...
Vladimir Prudnikov

@VladimirPrudnikov, nếu một ứng dụng có thể biết về tất cả các plugin tại thời điểm biên dịch, điều đó thật tuyệt vời. Tuy nhiên, ý tưởng là có thể thêm các plugin có thể sau khi ứng dụng được biên dịch. Điều này sẽ cho phép cắm các mô-đun thực sự năng động. Tuy nhiên, điều này sẽ yêu cầu các mô-đun cũng được biên dịch trước tại thời điểm chúng được triển khai - và tôi không chắc nó sẽ hoạt động như thế nào. Tôi cũng không chắc chắn làm thế nào để giữ cho phiên bản mô-đun plugin tương thích với Angular.
Anthony Gatlin

2

Tôi đã thực hiện một bản hack để tải và biên dịch các mô-đun khác trong thời gian khởi động, nhưng tôi không giải quyết được vấn đề phụ thuộc theo chu kỳ

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

sau đó trong AppModule thêm điều này:

{
        provide: APP_INITIALIZER,
        useFactory: AppsLoaderFactory,
        deps: [AppsLoader],
        multi: true
},

2

Tôi cũng đang tìm kiếm một hệ thống plugin ở góc 2/4 để phát triển môi trường RAD cho ứng dụng doanh nghiệp tại nơi làm việc. Sau một số nghiên cứu, tôi quyết định thực hiện một bộ sưu tập các thành phần giả được lưu trữ cơ sở dữ liệu (nhưng có thể nằm trong hệ thống tập tin).

Các thành phần được lưu trữ trong cơ sở dữ liệu dựa trên ng-động và việc thực hiện thành phần chính tương tự như sau:

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

            });

        });

    }

Mã javascript bên ngoài tương tự như các thành phần góc:

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

};

Và các mẫu của các thành phần giống như các mẫu góc cạnh:

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

Và cũng có thể được lồng nhau:

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

Mặc dù nó không hoàn hảo, nhưng các nhà phát triển của các thành phần tùy chỉnh có khung tương tự như trong angular2 / 4.


2

Nó có thể được thực hiện, "thủ công". Vì webpack không biết gì về mô-đun bên ngoài (trình cắm), anh ta không thể bao gồm chúng trong gói. Vì vậy, những gì tôi đã làm, là xem xét mã được tạo bởi webpack và tôi đã tìm thấy những chiếc mã này trong main.bundle.js:

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

Hãy xem xét mảng đó chứa gì:

  1. "./dashboard/dashboard.module" - đây là URL định tuyến của phù thủy mô-đun, chúng tôi muốn tải lười biếng, ví dụ: {path: 'dashboard', loadChildren: './dashboard/dashboard.module#DashboardModule'}
  2. "../../../../../src/app/dashboard/dashboard.module.ts" - đây là điểm vào (bộ điều khiển) lấy từ
  3. "dashboard.module" - tên tệp thực tế không có chunk.js (ví dụ: dashboard.module.chunk.js )

Vì vậy, theo lý thuyết, nếu bạn thêm mục nhập vào thuộc tính bản đồ định cấu hình định tuyến của bạn và theo mẫu, bạn có thể có một hệ thống trình cắm. Bây giờ thách thức là làm thế nào để thêm hoặc xóa các mục từ thuộc tính bản đồ đó. Rõ ràng nó không thể được thực hiện từ mã góc, nó nên được thực hiện cho công cụ bên ngoài.


2

Tôi đã cố gắng triển khai kiến ​​trúc plugin bằng cách sử dụng ABP, Angular và ASP.NET Core: https://github.com/chanjunweimy/abp_plugin_with_ui

Về cơ bản, tôi đã phát triển các plugin góc bằng cách sử dụng các ứng dụng góc khác nhau, sau đó tôi tự động thêm chúng lại với nhau.

Thông tin thêm về cách tôi đạt được nó:

Tôi có 2 ứng dụng angular-cli, 1 là ứng dụng cli góc chính và một ứng dụng khác là plugin angi cli. Vấn đề chúng ta gặp phải trong cách tiếp cận kiến ​​trúc plugin Angular-cli là cách chúng ta tích hợp chúng.

Ngay bây giờ, những gì tôi đã làm là, tôi chạy ng-build trên cả hai ứng dụng và đưa chúng vào thư mục "wwwroot", sau đó được lưu trữ trong máy chủ ASP.NET core 2.0. Một kho lưu trữ đơn giản hơn cho thấy ý tưởng này là Angular Nhiều ứng dụng: https://github.com/chanjunweimy/angular-mult Môn-app

abp_plugin_with_ui là một kho lưu trữ hoạt động trong việc phát triển một plugin chứa cả phụ trợ và Angular cli. Đối với phần phụ trợ, tôi đã sử dụng khung aspnetboilerplate, phần giao diện được phát triển bằng nhiều ứng dụng angular-cli.

Để ứng dụng chính được tích hợp với ứng dụng plugin, chúng tôi phải chạy "ng-build" trên cả hai ứng dụng (lưu ý rằng chúng tôi cũng phải thay đổi to href của ứng dụng plugin), sau đó chúng tôi di chuyển nội dung được xây dựng của plugin ứng dụng cli góc, vào thư mục "wwwroot" của ứng dụng chính. Sau khi đạt được tất cả điều này, chúng ta có thể chạy "dotnet run" để phục vụ Ứng dụng web ASP.NET Core 2.0 để lưu trữ các tệp tĩnh được tạo bởi "ng build".

Hy vọng nó sẽ giúp. Mọi ý kiến ​​đều được chào đón! ^^


Tôi đang cố gắng làm theo các tài liệu plugin của bạn, nhưng tôi nghĩ rằng tài liệu này đang bỏ qua một vài bước. Tôi xin lỗi nếu tôi đọc sai nó. Toàn bộ phần 'thêm plugin' không rõ ràng đối với tôi. Tôi đã làm theo từng bước này, nhưng tôi không thực sự thấy kết quả. Tôi nên xem gì trên cổng 4200 sau khi chạy vỏ điện? Tôi không thấy thư mục Plugins trong /aspnet-core/src/Todo.MainProject.Web.Host/. Tôi đã chạy powershell và thư mục đó không được tạo. Bất kỳ trợ giúp đánh giá cao. Tôi nghĩ rằng cách tiếp cận của bạn là những gì tôi cần, nhưng tôi hơi mờ về cách nó hoạt động.
Brian Kitt

Đồng ý. Tôi nên làm điều này trước khi đặt câu hỏi. Tôi đã dành thời gian để gỡ lỗi, và tìm ra câu trả lời của tôi. # 1) powershell không đặt .zip vào nơi cần đến, tôi cần tạo thư mục plugin và di chuyển zip. # 2) khi ứng dụng góc khởi động, nó sẽ tự động gọi trình tải và sao chép các plugin vào webroot. Đó là loại đánh vần, nhưng tôi hiểu rồi. # 3) Tôi phải sử dụng url để gọi plugin, nó không hiển thị ở bất cứ đâu. Tôi đã mong đợi nó sẽ ở trên bảng điều khiển. Cảm ơn cho công việc của bạn, đây là một đoạn mã đáng kể.
Brian Kitt


2

Tôi hiện đang trong cùng một nhiệm vụ như bạn, đang cố gắng tạo ra một Phiên bản góc cạnh có thể cắm được / có thể sử dụng được, và đó không phải là một vấn đề nhỏ.

Tôi thực sự tìm thấy những giải pháp khá hay, đọc cuốn sách Phát triển với góc cạnh của thiên tài Denys Vuyika , anh ấy thực sự trên cuốn sách giải thích một giải pháp khá hay, anh ấy nói về các plugin bên ngoài trên trang 356 của cuốn sách và sử dụng Rollup.js để đạt được Sau đó, anh ta xử lý để tải động các plugin bên ngoài đã được xây dựng trước đó bên ngoài ứng dụng của bạn.

Ngoài ra còn có hai thư viện / dự án khác giúp bạn đạt được kết quả mở rộng ng-packagrNx cho Agnular (từ Nrwl) mà chúng tôi đang buộc phải thực hiện sau này và tôi sẽ nói rằng nó không suôn sẻ như chúng tôi dự đoán, góc cạnh rất đơn giản không được xây dựng cho điều đó, vì vậy chúng tôi phải làm việc xung quanh một số cốt lõi về cách Angular và các ppls NX là một trong những điều tốt nhất về nó.

Chúng tôi chỉ mới bắt đầu Dự án nguồn mở, chúng tôi đang sử dụng Django + Mongo + Angular, (Chúng tôi đang gọi WebDjangular và một trong những cách tiếp cận khả thi của chúng tôi cho câu trả lời này, đó là Django sẽ phải viết một số tệp cấu hình JSON và xây dựng ứng dụng mỗi khi một plugin hoặc chủ đề mới được cài đặt và kích hoạt.

Những gì chúng tôi đã hoàn thành là, từ cơ sở dữ liệu, chúng tôi có thể sử dụng các thẻ cho các thành phần như trên plugin và thành phần này sẽ được in trên màn hình! Một lần nữa, dự án đang ở giai đoạn rất sớm, chúng tôi đang dựa trên kiến ​​trúc của mình một chút về Wordpress và chúng tôi còn rất nhiều thử nghiệm phải làm để đạt được ước mơ của mình: D

Tôi hy vọng Sách có thể giúp bạn và sử dụng Rollup.js tôi biết bạn sẽ có thể giải quyết vấn đề không tầm thường này.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.