2018 년 5 월 24 일 업데이트 : 우리는 이제 원래 게시물에서 +3 버전의 Angular를 사용하고 있으며 최종적으로 실행 가능한 솔루션이 없습니다. Lars Meijdam (@LarsMeijdam)은 확실히 볼만한 가치가있는 흥미로운 접근법을 고안했습니다. 독점 문제로 인해 원래 샘플을 게시 한 GitHub 리포지토리를 일시적으로 제거해야했습니다. 그러나 사본을 원하면 직접 메시지를 보낼 수 있습니다. 자세한 내용은 아래 주석을 참조하십시오.
Angular 6의 최근 아키텍처 변경으로 인해 솔루션에 더 가깝습니다. 또한 Angular Elements ( https://angular.io/guide/elements )는 몇 가지 구성 요소 기능을 제공하지만 원래이 게시물에서 설명한 것과는 다릅니다.
놀라운 Angular 팀의 누군가 가이 문제를 겪게되면이 기능에도 관심이 많은 다른 사람들이있는 것처럼 보입니다. 백 로그를 고려할 가치가 있습니다.
나는의 플러그 (플러그인) 프레임 워크 구현하고 싶은 Angular 2
, Angular 4
, Angular 5
, 또는 Angular 6
응용 프로그램을.
(플러그 가능한 프레임 워크를 개발하기위한 특정 사용 사례는 소형 컨텐츠 관리 시스템을 개발해야한다는 것입니다. 여기에서 자세히 설명 할 필요는없는 여러 가지 이유로 Angular 2/4/5/6
해당 시스템의 대부분의 요구에 거의 완벽하게 맞습니다.)
플러그 가능한 프레임 워크 (또는 플러그인 아키텍처) 란 특히 타사 개발자가 기본 응용 프로그램의 소스 코드에 직접 액세스하거나 지식없이 플러그 가능 구성 요소 를 사용하여 기본 응용 프로그램의 기능을 만들거나 확장 할 수있는 시스템을 의미 합니다. 또는 내부 작업 .
( ” 응용 프로그램의 소스 코드 나 내부 작업에 직접 액세스하거나 지식을 얻지 않고 “라는 문구 는 핵심 목표입니다.)
플러그 프레임 워크의 예는 같은 일반적인 콘텐츠 관리 시스템 포함 WordPress
또는 Drupal
.
Drupal과 같은 이상적인 상황은 이러한 플러그 가능 구성 요소 (또는 플러그인)를 폴더에 간단하게 배치하고 응용 프로그램이 자동으로 감지하거나 발견하게하고 마술처럼 “작동”하도록하는 것입니다. 앱이 실행되는 동안 핫 플러그 가능한 방식으로 발생하는 것이 가장 좋습니다.
나는 현재 (답변 결정하기 위해 노력하고 여러분의 도움으로 다음과 같은 다섯 개 가지 질문을).
- 실용성 :
Angular 2/4/5/6
애플리케이션을 위한 플러그인 프레임 워크는 실용적입니까? (지금까지는를 사용하여 진정한 플러그 가능한 프레임 워크를 만드는 실용적인 방법을 찾지 못했습니다Angular2/4/5/6
.) - 예상되는 과제 :
Angular 2/4/5/6
애플리케이션 의 플러그인 프레임 워크를 구현할 때 어떤 문제가 발생할 수 있습니까? - 구현 전략 :
Angular 2/4/5/6
애플리케이션 의 플러그인 프레임 워크를 구현하기 위해 어떤 특정 기술 또는 전략을 사용할 수 있습니까? - 모범 사례 :
Angular 2/4/5/6
애플리케이션 용 플러그인 시스템을 구현하기위한 모범 사례는 무엇입니까 ? - 대체 기술 : 경우 플러그인 프레임 워크가 되지 에 실제
Angular 2/4/5/6
응용 프로그램, 무엇을 상대적으로 동등한 기술 (예를 들어React
)이 적합 할 수있는 현대적인 반응성이 매우 높은 웹 응용 프로그램 ?
일반적으로 다음을 사용하는 Angular 2/4/5/6
것이 매우 바람직합니다.
- 당연히 엄청나게 빠릅니다.
- (초기로드 후) 매우 적은 대역폭을 소비합니다.
- 발자국이 비교적 작고 (후
AOT
및tree shaking
) 발자국이 계속 줄어 듭니다. - 고도로 기능적이며 Angular 팀과 커뮤니티는 생태계의 빠른 성장을 계속하고 있습니다.
- 이 같은 최고와 최신 웹 기술의 많은 잘 재생
TypeScript
및Observables
- 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-CLI
아마와 Angular 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
응용 프로그램의 모든 아키텍처를 이해하지 않고도 응용 프로그램을 설치하고 선택한 플러그인 을 설치할 수있는 방법을 찾고 싶습니다 . -
일반적으로 플러그 가능한 아키텍처를 제공함으로써 얻을 수있는 이점 중 하나는 타사 개발자가 시스템 기능을 확장하는 것이 매우 쉽다는 것입니다. 분명히, 이러한 개발자들은 그들이 연결하고있는 응용 프로그램에 대한 코드의 모든 복잡한 부분에 익숙하지 않을 것입니다. 일단 플러그인이 개발되면 기술을 덜 사용하는 다른 사용자도 단순히 애플리케이션과 선택한 플러그인을 설치할 수 있습니다. 그러나
Angular 2/4/5/6
비교적 복잡하고 학습 시간이 매우 길다. 더 복잡한 일에, 대부분의 생산Angular 2/4/5/6
응용 프로그램도 활용Angular-CLI
,Angular Universal
및WebPack
. 플러그인을 구현하는 사람은 아마도 강력한 작업 지식과 함께 이들 모두가 어떻게 결합되는지에 대한 최소한의 기본 지식을 가지고 있어야 할 것입니다.TypeScript
에 대한 합리적인 친숙 함NodeJS
. 지식 요구 사항이 너무 높아서 타사가 플러그인을 개발하기를 원하지 않습니까? -
대부분의 플러그인에는 일부 서버 측 구성 요소 (예 : 플러그인 관련 데이터 저장 / 검색)와 일부 클라이언트 측 출력이있을 수 있습니다.
Angular 2/4/5
특히 개발자는 런타임에 자체 템플릿을 주입하지 않아야합니다. 이는 심각한 보안 위험을 초래할 수 있습니다. 플러그인이 수용 할 수있는 많은 유형의 출력을 처리하려면 (예 : 그래프 표시) 사용자가 응답 스트림에 주입 된 콘텐츠를 다른 형식으로 만들 수 있도록 허용하는 것이 필요할 수 있습니다. 필자Angular 2/4/5/6
의 보안 메커니즘 을 비판적으로 파쇄하지 않고 어떻게 이러한 요구를 수용 할 수 있을지 궁금하다 . -
대부분의 프로덕션
Angular 2/4/5/6
응용 프로그램은Ahead of Time
(AOT
) 컴파일을 사용하여 사전 컴파일됩니다. (아마도 모두가 있어야합니다.) 플러그인이 사전 컴파일 된 응용 프로그램에 추가되거나 통합 될 수 있는지 확실하지 않습니다. 가장 좋은 시나리오는 기본 애플리케이션과 별도로 플러그인을 컴파일하는 것입니다. 그러나이 작업을 수행하는 방법을 잘 모르겠습니다. 폴백은 포함 된 플러그인을 사용하여 전체 애플리케이션을 다시 컴파일하는 것일 수 있지만 선택한 플러그인과 함께 애플리케이션을 자신의 서버에 설치하려는 관리 사용자에게는 약간 복잡합니다. -
에서
Angular 2/4/5/6
응용 프로그램, 특히 미리 컴파일 된 하나, 잘못된의 한 조각 또는 충돌 코드 전체 응용 프로그램을 중단 할 수 있습니다.Angular 2/4/5/6
응용 프로그램이 항상 디버그하기 가장 쉬운 것은 아닙니다. 잘못 작동하는 플러그인을 적용하면 매우 불쾌한 경험이 발생할 수 있습니다. 현재 동작하지 않는 플러그인을 정상적으로 처리하는 메커니즘을 알지 못합니다.
답변
도움이 될만한 솔루션으로 github에 리포지토리를 만들었습니다. UMD 번들 라이브러리를 느리게로드하는 Angular 6 라이브러리와 1 개의 기본 애플리케이션을 사용합니다. https://github.com/lmeijdam/angular-umd-dynamic-example
제안이 있으시면 언제든지 추가하십시오!
답변
Github 데모 앵귤러 플러그인 아키텍처
아이비는 무언가를 바꿀 수 있지만 당분간 Angular CLI Custom Builder를 사용하고 다음 요구 사항을 충족시키는 솔루션을 사용합니다.
- AOT
- 중복 코드를 피하십시오 (@ 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
내 기사에서 이에 대한 자세한 내용 :
답변
방금 책 ” 앵귤러로 개발하기 “에 대한 새로운 장을 출판했습니다 Angular 2+의 플러그인 주제를 다루는 외부 플러그인을 구축하려는 사람들에게 큰 관심을 가져야합니다.
키 포인트:
- 플러그인
- 문자열 이름을 기반으로 구성 요소 작성
- 외부 소스에서 구성로드
- 동적으로 변화하는 응용 프로그램 경로
- 외부 플러그인
- 플러그인 라이브러리 생성
- 애플리케이션에 플러그인로드
- 플러그인 콘텐츠가 포함 된 동적 경로
이 책은 무료로 제공되며 “원하는 금액을 지불”모델이 있습니다. 사본을 들고 도움이되기를 바랍니다.
답변
작업 플러그인 시스템 예제 응용 프로그램합니다 (github에의 REPO를 설립하기위한 헤이스에 감사합니다!) https://github.com/PacktPublishing/Mastering-Angular-2-Components/tree/master/angular-2-components-chapter-10을 기반으로 eBook 마스터 링 Angular 2 구성 요소
- 핵심 앱 구성 요소를 확장하는 플러그인 아키텍처
- 파일 플러그인 시스템 (핵심 구성 파일을 편집하거나 애플리케이션을 다시 컴파일 할 필요없이 플러그인 디렉토리 / 파일을 추가하기위한 것입니다!)
- 플러그인로드 및 동적 사용
- 플러그인을 즉시 활성화 / 비활성화하기위한 기초 플러그인 관리자 빌드
건배, 니클라스
답변
당신이 찾고있는 것은 게으른 모듈 로딩입니다. 예를 들면 다음과 같습니다.
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;
}
}
}
최고 … 톰
답변
부트 스트랩 시간에로드를 해킹하고 다른 모듈을 컴파일하지만 순환 종속성 문제를 해결하지 못했습니다.
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));
그런 다음 AppModule에서 다음을 추가하십시오.
{
provide: APP_INITIALIZER,
useFactory: AppsLoaderFactory,
deps: [AppsLoader],
multi: true
},
답변
나는 직장에서 엔터프라이즈 응용 프로그램을위한 RAD 환경을 개발하기 위해 각도 2/4의 플러그인 시스템을 찾고있었습니다. 몇 가지 연구를 한 후 데이터베이스 저장 pseudo-Angular 구성 요소 컬렉션을 구현하기로 결정했습니다.
데이터베이스 데이터베이스에 저장된 컴포넌트는 ng-dynamic을 기반으로
하며 주요 컴포넌트 구현은 다음과 유사합니다.
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();
}
});
});
}
외부 자바 스크립트 코드는 각도 구성 요소와 유사합니다.
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 (click)="customFunction1()">{{ ctx.model.title }}</a>
<input [(ngModel)]="ctx.model.title" type="text" />
그리고 중첩 될 수도 있습니다.
<a (click)="customFunction1()">{{ ctx.model.title }}</a>
<my-template [name]="childTemplateName"></my-template>
완벽하지는 않지만 사용자 지정 구성 요소 개발자는 angular2 / 4와 유사한 프레임 워크를 갖습니다.