angular: AoT Compiler unable to resolve module with "export default class"

I’m submitting a …

[x] bug report => search github for a similar issue or PR before submitting

Current behavior To allow a module to be loaded lazily, I define its route like so:

{
    path: 'report',
    loadChildren: '/app/report/report.module'
}

And I declare it as the default class in report.module.ts so the router will know what to load:

export default class ReportModule {}

Using export default class ReportModule {} instead of export class ReportModule {} when declaring modules breaks ngc. During compilation I get error:

can't resolve module C:/path/to/report.module.ts from C:/path/to/report.module.ts
Error: can't find symbol ReportModule exported from module C:/path/to/report.module.ts
    at ReflectorHost.findDeclaration (C:\path\to\@angular\compiler-cli\src\reflector_host.js:174:23)
    at _loop_1 (C:\path\to\@angular\compiler-cli\src\codegen.js:52:51)
    ...
Compilation failed

I left the orientation of the slashes (forward / and back \) as they appear in the console

Expected/desired behavior

An earlier version of the docs on ngModule suggested using export default to expose lazy-loaded modules. This works well with Just-in-Time compilation. So I expected the AoT compiler to be able to parse them as well

Reproduction of the problem

Try compiling an application with a module declared with export default

Please tell us about your environment:

  • Angular version: 2.0.0-rc.6
  • Browser: [all]
  • Language: [TypeScript 2]

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 45
  • Comments: 34 (14 by maintainers)

Commits related to this issue

Most upvoted comments

@frankforward don’t use default exports 😃

Same question here, any updates on when default exports will be supported by the AoT compiler?

Wow, 2019 is coming to an end, the problem still exist

I spent two hours tracing this down in my app. Googling the error message didn’t lead anywhere. Once I discovered it (by accident), I finally found this issue. In my case, the error message was slightly different and even less helpful: Unexpected value 'null' declared by the module AppModule.

Please make this a priority so other devs won’t waste time like I did.

Just place both export types and it works: @NgModule({}) export class MyModule { } export default MyModule;

Sorry, this is not priority, but we would accept a PR.

On Thu, Jan 26, 2017 at 6:28 AM, Peter Grman notifications@github.com wrote:

Hi, 4 months ago @robwormald https://github.com/robwormald wrote in #11975 (comment) https://github.com/angular/angular/issues/11975#issuecomment-250427362

… we do plan to support this.

Is there any chance that this would get supported with the upcoming version 4?

— You are receiving this because you were assigned. Reply to this email directly, view it on GitHub https://github.com/angular/angular/issues/11402#issuecomment-275400938, or mute the thread https://github.com/notifications/unsubscribe-auth/AAG1T1rqEaTSwB37sVgvECaikMW-WJYuks5rWK2ggaJpZM4J2dJR .

Any updates? I have the same problem with Angular 2.1.0 and typescript 2.0.3. Can we use “export default class” or not? It is useful to know if we must remove all default exports or not.

Thank u.

What if I’m building an Angular component library, and have an embedded third party lib that uses default exports, I have no control over it, and my lib doesn’t build because of this.

Hey folks,

default exports are now working in the Ivy compiler!

This can be fixed by providing the exported class through a factory provider. The following is an example providing MarkerClusterer from @google/markerclustererplus:

import MarkerClusterer from '@google/markerclustererplus';

export const MARKER_CLUSTERER_CLASS = new InjectionToken<new (...args: any) => MarkerClusterer>(
  'MarkerClustererPlus class from @google/markerclustererplus',
);

export function markerClustererClassFactory(): new (...args: any) => MarkerClusterer {
  return MarkerClusterer;
}

@NgModule({
  providers: [
    { provide: MARKER_CLUSTERER_CLASS, useFactory: markerClustererClassFactory },
  ],
})
export class SomeModule {}

@Injectable()
export class SomeService {
  constructor(@Inject(MARKER_CLUSTERER_CLASS) private markerClustererClass) {}
}
❯ ng --version

     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 8.3.23
Node: 10.16.1
OS: linux x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                            Version
------------------------------------------------------------
@angular-devkit/architect          0.803.23
@angular-devkit/build-angular      0.803.23
@angular-devkit/build-ng-packagr   0.803.23
@angular-devkit/build-optimizer    0.803.23
@angular-devkit/build-webpack      0.803.23
@angular-devkit/core               8.3.23
@angular-devkit/schematics         8.3.23
@angular/cli                       8.3.23
@ngtools/webpack                   8.3.23
@schematics/angular                8.3.23
@schematics/update                 0.803.23
ng-packagr                         5.7.1
rxjs                               6.5.4
typescript                         3.5.3
webpack                            4.39.2

This is still a thing, error message could be better: ‘ERROR in : Unexpected value ‘null’ imported by the module’ when you export a routing module as default.

If I hadn’t found a thread referencing the same error this would’ve been a pain to solve.

Sorry, this is not priority, but we would accept a PR.

Why not just making a PR if you really need that rather than waiting for years, this is open-source project…

@pavel-agarkov When I place both exports, AOT compiles, but I get the following error in production:

ERROR Error: Uncaught (in promise): Error: Cannot find 'default' in './registration/registration.module' Error: Cannot find 'default' in './registration/registration.module'

Hi, 4 months ago @robwormald wrote in https://github.com/angular/angular/issues/11975#issuecomment-250427362

… we do plan to support this.

Since than I didn’t find anything tangible if it will take another month, year or decade. Is there any chance that this would get supported with the upcoming version 4?

I think the compiler / codgen pipeline in general doesn’t handle default exports (yet)