当在Angular中的DI中使用从库导入的工厂函数时,AOT编译失败

前端之家收集整理的这篇文章主要介绍了当在Angular中的DI中使用从库导入的工厂函数时,AOT编译失败前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个Angular 6.1应用程序,它导入一些外部模块.

当我在AOT模式下编译应用程序时:

$ng build –aot

我收到这个错误

  1. ERROR in ./src/app.component.ngfactory.js
  2. Module not found: Error: Can't resolve '/home/user/project/node_modules/@acme/library/src/library/library' in '/home/user/project/src/app'
  3. resolve '/home/user/project/node_modules/@acme/library/src/library/library' in '/home/user/project/src/app'
  4. using description file: /home/user/project/package.json (relative path: ./src/app)
  5. Field 'browser' doesn't contain a valid alias configuration
  6. using description file: /home/user/project/node_modules/@acme/library/package.json (relative path: ./src/library/library)
  7. no extension
  8. Field 'browser' doesn't contain a valid alias configuration
  9. /home/user/project/node_modules/@acme/library/src/library/library doesn't exist
  10. .ts
  11. Field 'browser' doesn't contain a valid alias configuration
  12. /home/user/project/node_modules/@acme/library/src/library/library.ts doesn't exist
  13. .tsx
  14. Field 'browser' doesn't contain a valid alias configuration
  15. /home/user/project/node_modules/@acme/library/src/library/library.tsx doesn't exist
  16. .mjs
  17. Field 'browser' doesn't contain a valid alias configuration
  18. /home/user/project/node_modules/@acme/library/src/library/library.mjs doesn't exist
  19. .js
  20. Field 'browser' doesn't contain a valid alias configuration
  21. /home/user/project/node_modules/@acme/library/src/library/library.js doesn't exist
  22. as directory
  23. /home/user/project/node_modules/@acme/library/src/library/library doesn't exist
  24. [/home/user/project/node_modules/@acme/library/src/library/library]
  25. [/home/user/project/node_modules/@acme/library/src/library/library.ts]
  26. [/home/user/project/node_modules/@acme/library/src/library/library.tsx]
  27. [/home/user/project/node_modules/@acme/library/src/library/library.mjs]
  28. [/home/user/project/node_modules/@acme/library/src/library/library.js]
  29. @ ./src/app.component.ngfactory.js 12:0-92 30:102-122 30:186-206 33:204-224 33:289-309 36:204-224 36:289-309 45:102-122 45:187-207 51:102-122 51:187-207 120:102-122 120:187-207
  30. @ ./src/app/app.module.ngfactory.js
  31. @ ./src/main.ts
  32. @ multi ./src/main.ts

路径node_modules / @ acme / library / src / library / library指向library.d.ts文件,该文件存在于模块目录中.

如果我从外部包中完全删除键入信息,则应用程序将编译并正常工作.此外,如果我手动将所有打字合并到一个index.d.ts文件中,编译就完成了.

我认为编译器解析类型定义文件的方式有些不对,看起来因为某些原因它没有查找扩展名为.d.ts的文件.

更新1

外部模块@ acme / library也是由我开发和预编译的.它是一个简单的TypeScript库,包含一些导出的类和函数.它没有使用像Angular那样的装饰和东西.

它的package.json包含以下字段:

  1. "es2015": "index.es2015.js","main": "index.min.js","module": "index.es5.js","typings": "index.d.ts",

所有提到的文件都存在于包的根目录中.

更新2

经过进一步调查,看起来问题是由依赖注入引起的.请参阅下面的示例.

我正在使用自定义工厂提供程序,以便将一个Library实例注入组件的构造函数.

libraryFactory函数是从外部模块导入的,它看起来像这样:

  1. export function libraryFactory(): Library {
  2. const dep1 = new Dep1();
  3. const dep2 = new Dep2();
  4. return new Library(dep1,dep2);
  5. }

失败的例子

  1. import {Component} from '@angular/core';
  2.  
  3. import {Library,libraryFactory} from '@acme/library';
  4.  
  5.  
  6. @Component({
  7. selector: 'app-foo',templateUrl: './foo.component.html',providers: [
  8. {
  9. provide: Library,useFactory: libraryFactory
  10. }
  11. ]
  12. })
  13. export class FooComponent {
  14.  
  15. constructor(public library: Library) {
  16. }
  17.  
  18. }

工作实例

但是,如果我摆脱DI它编译并正常工作:

  1. import {Component} from '@angular/core';
  2.  
  3. import {Library,templateUrl: './foo.component.html'
  4. })
  5. export class FooComponent {
  6.  
  7. public library: Library;
  8.  
  9.  
  10. constructor() {
  11. this.library = libraryFactory();
  12. }
  13.  
  14. }

什么可能导致这个问题?

如果需要,我会很乐意提供更具体的信息.

Angular不知道要向Library类注入什么,因为在使用useFactory之前不会注入Dep1和Dep2.所以你可以在失败的例子中简单地将useFactory更改为useValue,然后它一定没问题.

要么

如果要将工厂用于库实例,则必须在库之前将Dep1和Dep2注入提供程序.如果Dep1和Dep2本身没有依赖关系,它必须工作.如果他们也有依赖关系,你也必须注入它们.

  1. import {Component} from '@angular/core';
  2.  
  3. import {Library,Dep1,Dep2} from '@acme/library';
  4.  
  5. const dep1instance = new Dep1();
  6. const dep2instance = new Dep2();
  7.  
  8. @Component({
  9. selector: 'app-foo',providers: [
  10. {
  11. provide: Dep1,useValue: dep1instance
  12. },{
  13. provide: Dep2,useValue: dep2instance
  14. },{
  15. provide: Library,useFactory: (dep1: Dep1,dep2: Dep2) => new Library(dep1,dep2),deps:[Dep1,Dep2]
  16. }
  17. ]
  18. })
  19. export class FooComponent {
  20.  
  21. constructor(public library: Library) {
  22. }
  23.  
  24. }

要么

您可以使用Injectible装饰器分割您的库,以实现角度DI兼容性. IMO简单,可维护和有用的选择.

猜你在找的Angularjs相关文章