Угловой компонент теряет свои метаданные во время переноса
ЕЩЕ ОДИН: Uncaught Error: Unexpected value 'UserDialogComponent' declared by the module 'AppModule'. Please add a @Pipe/@Directive/@Component annotation.
Текущее поведение
резюме: включая внешнюю библиотеку, которая использует reflect-metadata
вызывает ошибку, подобную этой: https://github.com/angular/angular/issues/15890
Ожидаемое поведение
Добавление внешней библиотеки, использующей тот же полифилл, не должно вызывать ошибок.
Минимальное воспроизведение задачи с инструкциями
Описание ошибки: Есть два компонента:
AppComponent и UserDialogComponent
Как я вижу, UserDialogComponent ведет себя так, как будто он не был @Component
но это не правда Я полагаю, что проблема основана на отражении метаданных. Если я удалю декораторы, добавленные kaop-ts
В библиотеке все идет хорошо. Но это работало до добавления UserDialogComponent:\
репо с ошибкой: https://github.com/k1r0s/angular2-aop-showcase/ branch: iss-angular-refle шаги для воспроизведения: клон репо, git checkout origin/iss-angular-отражение, установка npm, ng serve
дополнительная информация (изображения с трассировкой ошибок): https://imgur.com/a/Yz2qu
Прикрепленные изображения: С помощью инструментов Chrome dev, если вы установили "паузу при исключении", вы дважды заходите в стек вызовов и затем оцениваете: meta.declarations[1]
Вы должны получить ссылку на конструктор UserDialogComponent, а затем выполнить: Reflect.getMetadata("annotations", meta.declarations[1])
для того, чтобы получить метаданные компонента, но он возвращает неопределенное, тогда как Reflect.getMetadata("annotations", meta.declarations[0])
успешно вернет медададу AppComponent... это довольно странно..
Какова мотивация / вариант использования для изменения поведения?
Удаляя сторонние декораторы, угловые компоненты сохраняют свои метаданные
Среда
Angular version: 4.0.0
package.json (project was generated with angular-cli)
"dependencies": {
"@angular/animations": "^4.0.0",
"@angular/cdk": "^2.0.0-beta.8",
"@angular/common": "^4.0.0",
"@angular/compiler": "^4.0.0",
"@angular/core": "^4.0.0",
"@angular/forms": "^4.0.0",
"@angular/http": "^4.0.0",
"@angular/material": "^2.0.0-beta.8",
"@angular/platform-browser": "^4.0.0",
"@angular/platform-browser-dynamic": "^4.0.0",
"@angular/router": "^4.0.0",
"core-js": "^2.4.1",
"kaop-ts": "^1.4.0",
"rxjs": "^5.4.1",
"zone.js": "^0.8.14"
},
Browser:
- [x] Chromium (desktop) version `Version 59.0.3071.109 (Developer Build)`
For Tooling issues:
- Node version: v6.11.2
- Platform: Linux
Спасибо!
1 ответ
Как указал @yurzui, пакет lect-metadata переопределяет глобальные ссылки, поэтому он конфликтует, например, с core-js.
Решение, в моем случае, было заменить reflect-metadata
пакет для core-js
и затем, включите в мою сборку отраженную область видимости от core-js.
Правильное объяснение того, почему с одним компонентом не было никаких проблем, заключается в том, что декораторы оцениваются при объявлении класса, поэтому при оценке угловых декораторов безболезненно оценивать сторонние декораторы, так как javascript уже хранит метаданные в памяти и может быть доступ. Проблема была с другим компонентом, потому что после того, как первый компонент был объявлен, машинописный текст оценивает следующие декораторы методов из сторонних библиотек, которые используют reflect-metadata
переназначая текущий глобальный Reflect
объект... (загрязняющий глобальное пространство имен..) и затем angular пытается загрузить второй компонент, но @component больше не может хранить метаданные там, где его нужно разместить, поэтому angular жалуется на 2-й компонент не имеет @component
Декларация, которая раздражает и причудливая из первых рук.