angular: bug(compiler-cli): metadata resolution error when generating flat module with reference in re-export

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior

GIVEN

There is a HelloComponent in app/components/hello.component. There is a re-export of HelloComponent in app/components.ts, like:

export * from './components/hello.component'

In app.module.ts, import HelloComponent from app/components.ts (re-export), like:

// ...
import { HelloComponent } from './components'

@NgModule({
  declarations: [
    // ...
    HelloComponent,
  ],
  // ...
})
export class AppModule { }

Checked not relates to filename.

WHEN

Config it to generate a flat module:

{
  "angularCompilerOptions": {
    "flatModuleId": "hello",
    "flatModuleOutFile": "hello.js",
    "skipTemplateCodegen": true
  }
}

And call AOT compiler via ngc.

THEN

An error occur:

MACHINE_NAME:aot-reexport-issue zjyu$ $(yarn bin)/ngc -p src/tsconfig.app.json
: TypeError: Cannot read property 'module' of undefined
    at MetadataBundler.convertSymbol (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:264:57)
    at createReference (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:390:23)
    at MetadataBundler.convertReference (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:438:24)
    at MetadataBundler.convertExpression (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:367:33)
    at MetadataBundler.convertValue (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:348:25)
    at /Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:351:58
    at Array.map (<anonymous>)
    at MetadataBundler.convertValue (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:351:26)
    at MetadataBundler.convertValue (/Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:357:32)
    at /Users/USER_NAME/Projects/github/trotyl/aot-reexport-issue/node_modules/@angular/compiler-cli/src/metadata/bundler.js:351:58

The error is caused by this line, canonicalSymbol doesn’t have a declaration property in this scenario.

Expected behavior

Be able to compile.

Minimal reproduction of the problem with instructions

https://github.com/trotyl/aot-reexport-issue

Steps mentioned there.

What is the motivation / use case for changing the behavior?

Be able to get codes work.

Environment


Angular version: 5.1.0


Browser:
- [ ] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 8.9.2  
- Platform:  Mac 

Others:

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 39
  • Comments: 22 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Any updates?

Any update here?

Importing it from where it is defined is work for me.

It is a problem for me as well, with @angular/cli 7.2.6 & @angular/cli 7.3.3. Is there any plan to fix this?

I noticed unexpected (for me) behavior:

//== Class that use interface from barrel-file
import { IBodyInterface } from '../interfaces'; // => Import from barrel

export class MyModel {
  public Body: IBodyInterface;
}

//== Barrel
export { IBodyInterface } from './body.interface';

In this case i got error TypeError: Cannot read property 'module' of undefined. But if edit export string in barrel file to export * from './body.interface'; build error will disappear

Is there any workaround ?

The issue https://github.com/ng-packagr/ng-packagr/issues/1173#issuecomment-551577679 referred me to this issue.

This issue prevents my library to use secondary-entry points and would save a lot of package size because of non-tree-shakable third-party libs. Neither is Ivy a thing for library-authors yet nor is there a workaround for this issue (at least I could not get it working)

How can this be a very low priority issue?

If this is not related to this issue I can open a new issue instead.

Addition to this issue

I tried to create two secondary entry points. One does work, one does not and I can’t see a difference.

This does work

ui/charts/package.json

{
  "ngPackage": {
    "lib": {
      "entryFile": "../src/lib/components/data/chart/public_api.ts",
      "umdModuleIds": {
        "chart.js": "chart.js"
      }
    }
  },
  "peerDependencies": {
    "chart.js": "^2.8.0"
  }
}

public_api.ts

export { ChartModule } from './nx-chart.module';
export { ChartBarComponent } from './chart-bar/chart-bar.component';
export { ChartLineComponent } from './chart-line/chart-line.component';

This does not work

ui/object-editor/package.json

{
  "ngPackage": {
    "lib": {
      "entryFile": "../src/lib/components/inputs/object-editor/public_api.ts",
      "umdModuleIds": {
        "ang-jsoneditor": "ang-jsoneditor",
        "jsoneditor": "jsoneditor"
      }
    }
  },
  "peerDependencies": {
    "ang-jsoneditor": "^1.9.0",
    "jsoneditor": "^8.0.0"
  }
}

public_api.ts

export { ObjectEditorModule } from './object-editor.module';
export { ObjectEditorComponent } from './object-editor.component';
export { ObjectEditorSectionComponent } from './object-editor-section/object-editor-section.component';

Error message

------------------------------------------------------------------------------
Building entry point 'ui/object-editor'
------------------------------------------------------------------------------
× Compiling TypeScript sources through NGC
ERROR: Cannot read property 'module' of undefined
An unhandled exception occurred: Cannot read property 'module' of undefined
See "..." for further details.

Further information

@angular-devkit/architect          0.1100.5
@angular-devkit/build-angular      0.1100.5
@angular-devkit/build-ng-packagr   0.1001.4
@angular-devkit/core               11.0.5
@angular-devkit/schematics         11.0.5
@angular/cdk                       11.0.3
@angular/flex-layout               11.0.0-beta.33
@schematics/angular                11.0.5
@schematics/update                 0.1100.5
ng-packagr                         11.0.3
rxjs                               6.6.2
typescript                         4.0.3

Conclusion

The only difference I spot is the dependencies of both entry points. I’d be happy to help with further information if you need them.

Instead of index.ts files,

import { SomeComponent, SomeService } from '../something';

we’re using private Angular Modules

import { SomeModule } from '../something.module';

This helps in a few cases to reduce direct referencing.

But index.ts files would be much better!!!

Any ETA on this ? Resolving from index barrel is kind of important on large, multi-teams project…

For Angular Library make sure your index barrel are exported in your library main index barrel (aka public_api)

I was getting this error in my angular library when I imported like:

import { thing } from 'directory';

But this workaround fixed it for me:

import { thing } from 'directory/index';

Marking as fixed by Ivy but still an issue today, as libraries are still built for VE therefor dependent on the metedata bundler.

We are running into this issue as well (ng-packagr uses this approach rendering the solution useless). Just with a single SharedModule that is reexported through an index file. It breaks. The error is thrown on line 344 of the bundler.ts file const module = this.getMetadata(declaration.module); . declaration is undefined. The declaration is found on the symbol just not on the canonicalSymbol.