Skip to content

No NgModule metadata found for 'AppModule' (again) #11218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wiltzius opened this issue Jun 13, 2018 · 17 comments
Closed

No NgModule metadata found for 'AppModule' (again) #11218

wiltzius opened this issue Jun 13, 2018 · 17 comments
Labels
area: @ngtools/webpack feature Issue that requests a new feature
Milestone

Comments

@wiltzius
Copy link

Bug Report or Feature Request (mark with an x)

- [X] bug report -> please search issues before submitting
- [ ] feature request

Area

- [X] devkit
- [ ] schematics

Versions

node v8.11.2
npm version 5.6.0 (tho I use yarn 1.7.0)
MacOS High Sierra

Repro steps

Repro case with instructions here:

https://github.com/wiltzius/ng-toolkit/tree/angular_and_webpack_demystified_step3

The log given by the failure

app.js:861 Uncaught Error: No NgModule metadata found for 'class{}'.
at e.resolve (app.js:861)
at e.getNgModuleMetadata (app.js:839)
at e._loadModules (app.js:1065)
at e._compileModuleAndComponents (app.js:1065)
at e.compileModuleAsync (app.js:1065)
at e.compileModuleAsync (app.js:1365)
at e.bootstrapModule (app.js:220)
at Module. (app.js:1373)
at n (app.js:1)
at app.js:1

Desired functionality

The @ngtools/webpack plugin doesn't produce any runtime errors?

Mention any other details that might be useful

This is roughly the same issue that's described in issue #8798 however that issue has a lot of different complaints in it and has been closed, so I thought it would be cleaner as a new one.

@alexzuza
Copy link

You wrote in your tsconfig.json

"angularCompilerOptions": {
    "mainPath": "./app/main.ts"
}

I could be wrong but seems there is no such option here. Anyway your path is incorrect. It should be ./src/main.ts

If you open webpack.config.json you can specify mainPath there.

new AngularCompilerPlugin({
  tsConfigPath: './tsconfig.json',
  mainPath: './src/main.ts',   <==== this line
  sourceMap: true
})

Also you should inject your scripts in body instead of head when use HtmlWebpackPlugin otherwise angular won't find my-app element when bootstrapping app.

new HtmlWebpackPlugin({
  template: __dirname + '/src/index.html',
  output: __dirname + '/dist',
  inject: 'body'   <=== this line
}),

Another way to solve your issue is use angularCompilerOptions.entryModule option like:

"angularCompilerOptions": {
  "entryModule": "src/app/app.module#AppModule"
}

@wiltzius
Copy link
Author

Ah, yes I see -- the angularCompilerOptions are not the same as the AngularCompilerPlugin options, and the mainPath can only be set in the latter not in the former. That does indeed explain it, thank you for the help! Sorry this wasn't a real bug.

@wiltzius
Copy link
Author

Hmm, I think there's still something going on here that doesn't quite work. The minimal test case I originally came up with did indeed have the problems you pointed out, thank you. We're still having trouble in our real app trying to use AngularCompilerPlugin.

It seems related to the fact that it's a hybrid AngularJS and Angular 6 app. Here's another repro, slightly more complicated than the original but incorporating the fixes that you originally pointed out:

https://github.com/wiltzius/ng-toolkit/tree/example-breakage-2

I've tried both the entryModule approach and the mainPath approach but they both seem to have the same problem.

Is there some specific way that AngularCompilerPlugin needs to be set up to work with a hybrid AngularJS + Angular app?

Thank you again.

@wiltzius wiltzius reopened this Jul 10, 2018
@alexzuza
Copy link

@wiltzius Hey again

You should go through the following steps:

  1. Open webpack.config.js
    https://github.com/wiltzius/ng-toolkit/blob/5785dfa4fd61faaa7da3b745c80f1ddc910a1f4a/webpack.config.js#L38

  2. Replace './src/app/app.module.ts#AppModule' with './src/app/app.module#AppModule'
    Note i removed .ts

  3. Open main.ts
    https://github.com/wiltzius/ng-toolkit/blob/5785dfa4fd61faaa7da3b745c80f1ddc910a1f4a/src/main.ts#L16-L17

  4. Replace

const platformRef = platformBrowserDynamic();
return platformRef.bootstrapModule(AppModule);

with

return platformBrowserDynamic().bootstrapModule(AppModule);

Don't ask me why is it so :)))

Now it's time to get the following error :)

app.js:formatted:43405 Unhandled Promise rejection: StaticInjectorError(Dr)[$injector]:
StaticInjectorError(Platform: core)[$injector]:
NullInjectorError: No provider for $injector!

@wiltzius
Copy link
Author

Wow! Thank you, once again. That's pretty unexpected haha.

I copied that line of code about platformRef bootstrapping directly from the Angular docs:

https://angular.io/guide/upgrade-performance#specifying-a-factory-for-the-angular-module

So if a specific invocation of platformRef bootstrapping is required by @ngtools/webpack, I wonder if maybe it should be mentioned somewhere in the @ngtools/webpack docs?

@clydin clydin added the feature Issue that requests a new feature label Jul 19, 2018
@HarelM
Copy link

HarelM commented Aug 31, 2018

I would like the following code in my main.ts file work with AOT - currently it breaks:

if (environment.isCordova) {
    let onDeviceReady = () => {
        window.open = cordova.InAppBrowser.open;
        platformBrowserDynamic().bootstrapModule(ApplicationModule);
    };
    document.addEventListener("deviceready", onDeviceReady, false);
} else {
    platformBrowserDynamic().bootstrapModule(ApplicationModule);
}

I know I can do replace the main.ts when compiling to cordova, but the above still doesn't work in cordova due to the fact that it is ran inside the onDeviveReady method...
Any suggestions how to solve this?

@alexzuza
Copy link

@HarelM Will this work for you?

if (environment.isCordova) {
    let onDeviceReady = () => {
        window.open = cordova.InAppBrowser.open;
        bootstrapFn();
    };
    document.addEventListener("deviceready", onDeviceReady, false);
} else {
    bootstrapFn();
}

function bootstrapFn() {
  platformBrowserDynamic().bootstrapModule(ApplicationModule);
}

@HarelM
Copy link

HarelM commented Sep 19, 2018

@alexzuza Thanks for the tip!
I have tested it and it works.
Never the less, there's a bug here.

@JuanEstebanKatz
Copy link

I solve the issue, in the file main.ts, I remove this part .catch(err => console.error(err)); and the final line is just: platformBrowserDynamic().bootstrapModule(AppModule);

@shraoned
Copy link

I solve the issue, in the file main.ts, I remove this part .catch(err => console.error(err)); and the final line is just: platformBrowserDynamic().bootstrapModule(AppModule);

I think that's not great solution for this error...You need to add
"files": [ "../src/app/app.module.ts" ]
in your tsconfig.app.json file...

@SanaBilal
Copy link

I am facing the same issue and I tried by adding the below line to my tsconfig.app.json file but it didn't work:
"files": [ "../src/app/app.module.ts" ]

Can someone please help me with this?

@alyahmedaly
Copy link

alyahmedaly commented Dec 3, 2019

@alexeagle I think I found the root cause in my case I was having a custom builder and by using it I was getting this error and if I switched to cli one it works totally fine after some debugging if found that compile cli try to read class declaration https://github.com/angular/angular/blob/5332b04f35e60ddb2567b2288efd561e25a2a23b/packages/compiler-cli/src/metadata/collector.ts#L299
but ts.SyntaxKind.ClassDeclaration kind (240,244) is different between typescript versions for example (3.7 and 3.3)
so in my case, my builder was not an external dependency I was trying something in angular project
apps/builder and in angular.json "builder": "./builder:todo" and this folder was a package with different ts version

I hope it helps someone else short answer make sure typescript version is consistent between your packages and maybe global ng

@shyambhiogade
Copy link

if nothing else works try following to create the ngmodule offline

if (environment.production) {
        // there is no need of this if block, angular internally creates following code structure when it sees --prod
        // but at the time of writting this code, else block was not working in the production mode and NgModule metadata
        // not found for AppModule error was coming at run time, added follow code to fix that, it can be removed probably 
        // when angular is upgraded to latest version or if it start working automatically. :)
        // we could also avoid else block but building without --prod saves time in building app locally.
        platformBrowser(extraProviders).bootstrapModuleFactory(<any>AppModuleNgFactory);
    } else {
        platformBrowserDynamic(extraProviders).bootstrapModule(AppModule);
    }

@zizifn
Copy link

zizifn commented Mar 26, 2020

@HarelM Will this work for you?

if (environment.isCordova) {
    let onDeviceReady = () => {
        window.open = cordova.InAppBrowser.open;
        bootstrapFn();
    };
    document.addEventListener("deviceready", onDeviceReady, false);
} else {
    bootstrapFn();
}

function bootstrapFn() {
  platformBrowserDynamic().bootstrapModule(ApplicationModule);
}

Thanks! @alexzuza But why this work in AOT????

@MaheshB0ngani
Copy link

Might be helpful for someone. Earlier (few months ago) I turned on npm config set link true to reduce the node_modules size, but now understood it has consequences like this. For me resetting the npm config npm config edit or particularly npm config set link false worked for me. I almost wasted 3 days for this.

@alan-agius4
Copy link
Collaborator

Thanks for reporting this issue. This issue is now obsolete due to changes in the recent releases. Please update to the most recent Angular CLI version.

If the problem persists after upgrading, please open a new issue, provide a simple repository reproducing the problem, and describe the difference between the expected and current behavior.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Jul 2, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: @ngtools/webpack feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests