Я работаю над приложением Angular2, которое поставляется вместе с webpack. Все работает отлично. Однако это связанное приложение будет отправлено независимо и во время выполнения, прежде чем загружать приложение, мне нужно указать другие NgModules в один из модулей, которые я установил в своем приложении. В основном думайте об этом как о двух пучках, включенных в index.html, и когда bootstraped, bundle 1 переходит в bundle2. Загрузите только 2 загрузочных приложения. Поэтому я сделал несколько экспериментов, которые я хотел бы поделиться с вами, чтобы пролить свет на это (я мог бы принять довольно грязный и совершенно неправильный подход, поэтому, пожалуйста, исправьте, если так. Я не против грязного, если это это единственный способ, которым это может работать.). Только требование состоит в том, что во время транспиляции ничего не нужно делать. Требование состоит в том, что я могу включить один или несколько пакетов в свой index.html, и они могут быть подключены к реальному приложению без каких-либо предварительных знаний друг о друге.
Причина, по которой я это делаю, в первую очередь заключается в том, что я работаю на платформе, где другие разработчики могут подключаться к коду, устанавливая расширения. Это означает, что я доставляю исходный пакет, который не знает других пакетов о времени пересылки что-то еще. Это было легко в AngularJS, но переход на Angular2 и далее, это уже не так просто.
Мне удалось отложить загрузку приложения с помощью следующего подхода:
В main.ts:
window["platformBrowserDynamicRef"] = platformBrowserDynamic();
window["appModule"] = AppModule;
Это отлично работает, и когда я вызываю bootstrap вручную, приложение запускается просто отлично. Я создал еще один пакет, который независимо работает отлично как другое приложение.
Когда я пытаюсь связать их вместе, импортируя компоненты в неявный массив, как указано выше, и я загружаю приложение, я получаю сообщение об ошибке, которое я не знаю, что делать.
window["app"].modulesImport.push(CommonModule);
window["app"].modulesImport.push(FormsModule);
window["app"].modulesImport.push(BrowserModule);
window["app"].modulesImport.push(NgGridModule);
window["app"].modulesImport.push(ReactiveFormsModule);
window["app"].modulesImport.push(BrowserAnimationsModule);
window["app"].modulesImport.push(HttpModule);
@NgModule({
imports: window["app"].modulesImport,
declarations: [
DYNAMIC_DIRECTIVES,
PropertyFilterPipe,
PropertyDataTypeFilterPipe,
LanguageFilterPipe,
PropertyNameBlackListPipe
],
exports: [
DYNAMIC_DIRECTIVES,
CommonModule,
FormsModule,
HttpModule
]
})
export class PartsModule {
static forRoot()
{
return {
ngModule: PartsModule,
providers: [ ], // not used here, but if singleton needed
};
}
}
Наличие модулей в неявном массиве отлично работает, но как только я добавляю модуль из другого моего пакета, я получаю следующую ошибку:
Uncaught Error: Unexpected value 'ExtensionsModule' imported by the module 'PartsModule'. Please add a @NgModule annotation.
at syntaxError (http://localhost:3002/dist/app.bundle.js:43864:34) [<root>]
at http://localhost:3002/dist/app.bundle.js:56319:44 [<root>]
at Array.forEach (native) [<root>]
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>]
at CompileMetadataResolver.getNgModuleSummary (http://localhost:3002/dist/app.bundle.js:56244:52) [<root>]
at http://localhost:3002/dist/app.bundle.js:56317:72 [<root>]
at Array.forEach (native) [<root>]
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>]
at CompileMetadataResolver.getNgModuleSummary (http://localhost:3002/dist/app.bundle.js:56244:52) [<root>]
at http://localhost:3002/dist/app.bundle.js:56317:72 [<root>]
at Array.forEach (native) [<root>]
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:3002/dist/app.bundle.js:56302:49) [<root>]
at JitCompiler._loadModules (http://localhost:3002/dist/app.bundle.js:67404:64) [<root>]
at JitCompiler._compileModuleAndComponents (http://localhost:3002/dist/app.bundle.js:67363:52) [<root>]
Я также попытался скомпилировать ExtosModule с AoT, который тоже не работает. Я также попробовал динамически компилировать компоненты во время выполнения с помощью JitCompiler, чтобы узнать, могу ли я их подключить к этому приложению. Тем не менее, ту же ошибку.
Являются ли компоненты украшенными во время развертывания приложения или во время транспиляции? Подглядывая модули в моем неявном массиве, я вижу, что они украшены, но мой нет. Этот веб-пакет вставляет код вызова метода декоратора? Я предполагаю, что информация о декораторе теряется во время транспиляции, поэтому, возможно, мне нужно временно сохранить его так или иначе, чтобы я мог схватить его в другом месте. (обратите внимание, что extensionsmodule в качестве первого элемента не содержит массив декоратора)
Я предполагаю, что Im ищет указатели на то, как двигаться дальше отсюда. Может быть, функция аннотации NgModule станет хорошим местом для начала. Не удалось найти нигде.
ИЗМЕНИТЬ
вникая в проблему, я пробовал ленивый подход к загрузке с использованием Router, где сначала я получаю эту ошибку, пытаясь загрузить ее с помощью js файла (вкладка в сети показывает, что он никогда не выдает запрос на файл ):
const appRoutes: Routes = [
{
path: 'edit-entity/:type/:id/:culture',
component: EntityEditor,
resolve: {
entity: EntityResolver,
navigation: NavigationResolver
},
data: { shouldDetach: true},
loadChildren: "/dist/extensions.bundle.js#ExtensionsBundle",
},
{
path: '',
component: Dashboard,
resolve: {
navigation: NavigationResolver
},
data: { shouldDetach: true}
}
];
Разрешает следующую ошибку: "Не удалось найти модуль с именем ExtensionsModule.js"
Во-вторых, я попытался использовать функцию loadChildren следующим образом:
const appRoutes: Routes = [
{
path: 'edit-entity/:type/:id/:culture',
component: EntityEditor,
resolve: {
entity: EntityResolver,
navigation: NavigationResolver
},
data: { shouldDetach: true},
loadChildren: () => {
//"/dist/extensions.bundle.js#ExtensionsModule",
// return System.import('./dynamic.module').then((comp: any) => {
// return comp.otherExport;
// });
return window["lux"].modulesLazyImport[0];
}
},
{
path: '',
component: Dashboard,
resolve: {
navigation: NavigationResolver
},
data: { shouldDetach: true}
}
];
Решает в:
app.bundle.js:1548 ERROR Error: Uncaught (in promise): Error: No NgModule metadata found for 'ExtensionsModule'.
Error: No NgModule metadata found for 'ExtensionsModule'.
at NgModuleResolver.resolve (app.bundle.js:55709) [angular]
at CompileMetadataResolver.getNgModuleMetadata (app.bundle.js:56288) [angular]
at JitCompiler._loadModules (app.bundle.js:67404) [angular]
at JitCompiler._compileModuleAndComponents (app.bundle.js:67363) [angular]
at JitCompiler.compileModuleAsync (app.bundle.js:67325) [angular]
at ModuleBoundCompiler.compileModuleAsync (app.bundle.js:67693) [angular]
at MergeMapSubscriber.project (app.bundle.js:30608) [angular]
at MergeMapSubscriber._tryNext (app.bundle.js:69744) [angular]
at MergeMapSubscriber._next (app.bundle.js:69734) [angular]
at MergeMapSubscriber.Subscriber.next (app.bundle.js:14584) [angular]
at ScalarObservable._subscribe (app.bundle.js:69206) [angular]
at ScalarObservable.Observable.subscribe (app.bundle.js:118) [angular]
at MergeMapOperator.call (app.bundle.js:69709) [angular]
at Observable.subscribe (app.bundle.js:115) [angular]
at NgModuleResolver.resolve (app.bundle.js:55709) [angular]
at CompileMetadataResolver.getNgModuleMetadata (app.bundle.js:56288) [angular]
at JitCompiler._loadModules (app.bundle.js:67404) [angular]
at JitCompiler._compileModuleAndComponents (app.bundle.js:67363) [angular]
at JitCompiler.compileModuleAsync (app.bundle.js:67325) [angular]
at ModuleBoundCompiler.compileModuleAsync (app.bundle.js:67693) [angular]
at MergeMapSubscriber.project (app.bundle.js:30608) [angular]
at MergeMapSubscriber._tryNext (app.bundle.js:69744) [angular]
at MergeMapSubscriber._next (app.bundle.js:69734) [angular]
at MergeMapSubscriber.Subscriber.next (app.bundle.js:14584) [angular]
at ScalarObservable._subscribe (app.bundle.js:69206) [angular]
at ScalarObservable.Observable.subscribe (app.bundle.js:118) [angular]
at MergeMapOperator.call (app.bundle.js:69709) [angular]
at Observable.subscribe (app.bundle.js:115) [angular]
at resolvePromise (app.bundle.js:77503) [angular]
at resolvePromise (app.bundle.js:77488) [angular]
at :3000/dist/app.bundle.js:77537:17 [angular]
at Object.onInvokeTask (app.bundle.js:4599) [angular]
at ZoneDelegate.invokeTask (app.bundle.js:77289) [angular]
at Zone.runTask (app.bundle.js:77179) [<root> => angular]
at drainMicroTaskQueue (app.bundle.js:77433) [<root>]
at HTMLDivElement.ZoneTask.invoke (app.bundle.js:77364) [<root>]
ИЗМЕНИТЬ Я думал, что, возможно, ошибка была в том, что мои аннотации никогда не назывались. Не уверен, что так. Я решил пойти на ES5 и направить компонент в мой неявный список, как показано ниже. Такая же ошибка возникает, когда вы пытаетесь подтолкнуть компонент к части объявлений part.module.ts.
var HelloWorldComponent = function () {
};
HelloWorldComponent.annotations = [
new ng.core.Component({
selector: 'hello-world',
template: '<h1>Hello World!</h1>',
})
];
window["lux"].componentsLazyImport.push(HelloWorldComponent);
Итак, это ошибка в Angular 4.0.0 или вообще не возможно создать механизм плагина?
С уважением Morten