Angular-cli: --aot fails to build with no entryModule error

Created on 25 Oct 2016  Â·  41Comments  Â·  Source: angular/angular-cli

OS?

osX El Capitan

Versions.

angular-cli: 1.0.0-beta.18
node: 6.3.1
os: darwin x64

Repro steps.

When trying to use --aot on an app without the standard app.module.ts pattern the build fails with the below error. As per the documentation tried adding the following to the tsconfig and that did not resolve the issue.

  "angularCompilerOptions": {
    "entryModule": "app/wfa-ng2.module#WfaNg2Module"
  }

The log given by the failure.

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.
Error: Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.
    at Object.resolveEntryModuleFromMain (/Users/zchapple/code/wfa-ts/node_modules/@ngtools/webpack/src/entry_resolver.js:143:15)
    at AotPlugin._setupOptions (/Users/zchapple/code/wfa-ts/node_modules/@ngtools/webpack/src/plugin.js:105:77)
    at new AotPlugin (/Users/zchapple/code/wfa-ts/node_modules/@ngtools/webpack/src/plugin.js:34:14)
    at Object.exports.getWebpackAotConfigPartial (/Users/zchapple/code/wfa-ts/node_modules/angular-cli/models/webpack-build-typescript.js:57:13)
    at new NgCliWebpackConfig (/Users/zchapple/code/wfa-ts/node_modules/angular-cli/models/webpack-config.js:18:42)
    at Class.exports.default.Task.extend.run (/Users/zchapple/code/wfa-ts/node_modules/angular-cli/tasks/build-webpack.js:17:22)
    at Class.Command.extend.run (/Users/zchapple/code/wfa-ts/node_modules/angular-cli/commands/build.js:50:26)
    at Class.<anonymous> (/Users/zchapple/code/wfa-ts/node_modules/angular-cli/lib/models/command.js:152:17)
    at tryCatch (/Users/zchapple/code/wfa-ts/node_modules/rsvp/dist/lib/rsvp/-internal.js:215:12)
    at invokeCallback (/Users/zchapple/code/wfa-ts/node_modules/rsvp/dist/lib/rsvp/-internal.js:230:13)
    at publish (/Users/zchapple/code/wfa-ts/node_modules/rsvp/dist/lib/rsvp/-internal.js:198:7)
    at flush (/Users/zchapple/code/wfa-ts/node_modules/rsvp/dist/lib/rsvp/asap.js:85:5)
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)
1 (urgent) bufix

Most helpful comment

I have been facing the same issue when I have tried to load Module according to if statement.

const url = location.href;
if (url.indexOf('.') > -1) {
   platformBrowserDynamic().bootstrapModule(PreviewModule);
} else {
   platformBrowserDynamic().bootstrapModule(LandingModule);
}

This code could not compile with message:

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

To fix this error I have made another typescript file (just as @LukasBombach explained):

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {LandingModule} from './app/landing/landing.module';

export function bootstrapLandingModule() {
  platformBrowserDynamic().bootstrapModule(LandingModule);
}

and now main.ts look like this:

const url = location.href;
if (url.indexOf('.') > -1) {
  platformBrowserDynamic().bootstrapModule(PreviewModule);
} else {
  bootstrapLandingModule();
}

I can compile without any problems now.

ng version

@angular/cli: 1.0.0-beta.30
node: 7.5.0
os: darwin x64
@angular/common: 2.4.6
@angular/compiler: 2.4.6
@angular/core: 2.4.6
@angular/forms: 2.4.6
@angular/http: 2.4.6
@angular/material: 2.0.0-beta.1
@angular/platform-browser: 2.4.6
@angular/platform-browser-dynamic: 2.4.6
@angular/router: 3.4.6
@angular/cli: 1.0.0-beta.30
@angular/compiler-cli: 2.4.6

All 41 comments

Ran into the same issue. With the current configuration, auto discovery takes precedence over tsconfig.

Did some more debugging on this and found that the issue is around the parsing of the main.ts file. @clydin is right in that the CLI tries to resolve first. Which it does resolve my main.ts file correctly but because I have my bootstrap module wrapped in a DOMContentLoaded block it cannot parse the bootstrapModule. Putting your bootstrap in this block breaks.

import './polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { WfaNg2Module } from './app';

if (environment.production) {
  enableProdMode();
}

document.addEventListener('DOMContentLoaded', function () {
  platformBrowserDynamic().bootstrapModule(WfaNg2Module, []);
}, false);

Have you found a solution/work-around? I'm experiencing a similar issue which is likely caused by a custom function wrapping the bootstrapModule call.

It would seem that the only the top-level of the main.ts file is searched for the bootstrapModule call. By allowing it to search into nested calls(change false to true) it picks it up properly, and works for me.

Source: https://github.com/angular/angular-cli/blob/master/packages/webpack/src/entry_resolver.ts#L151.

I have a similar setup that leads to this error:

import './polyfills.ts';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/';
import { AppSettings } from './app/app.settings';

if (environment.production) {
  enableProdMode();
}

declare var fetch: any;

fetch('config.json', {method: 'get'}).then(res => {
  res.json().then(settings => {
    AppSettings.settings = settings;
    platformBrowserDynamic().bootstrapModule(AppModule);
  });
});

When can we expect a fix for that to be available through NPM?. For now I manually changed the file as @uitgewis suggested.

Even I am waiting for the fix through npm. Please update once it is available.

I get this same error. If I remove the catch handler it works.

platformBrowserDynamic().bootstrapModule(AppModule);/*.catch(err => {
    console.error(err);
});*/

can confirm @pietie's issue. Seems like an issue in the entry_resolver.ts here.

Actually, if I manage to, I'll try and fix this thing. Just have to figure out how to properly build the CLI locally and run it against my broken project.

Apparently..

// works
platformBrowserDynamic().bootstrapModule(AppModule);

// works
var promise = platformBrowserDynamic().bootstrapModule(AppModule);
promise.then(() => console.log('test'));

// doesn't work
platformBrowserDynamic().bootstrapModule(AppModule).then(() => console.log('test'));

I got this error wen I use polymer with angular cli . to use that I had to creat
main-polymer.ts

document.addEventListener('WebComponentsReady', () => {
  require('./main.ts');
}
);

and
main.ts

import './polyfills.ts';

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { environment } from './environments/environment';
import { AppModule } from './app/';

if (environment.production) {
  enableProdMode();
}

    platformBrowserDynamic().bootstrapModule(AppModule);

and in
angular-cli.json

I have to set
'main' : 'main-polymer.ts'

How I'm gone workaround this problem

Also breaks a hybrid app (angular 1 and 2) using the upgradeAdapter to bootstrap:

upgradeAdapter.bootstrap(document.body, ['app']);

@rumes, in what directory did you place the main-polymer.ts file you created?

@Chris-Vere /src

i used @juristr 's suggestion and it worked! Thanks,

I have the same config that @rumes and it is working fine with angular-cli: 1.0.0-beta.21, but breaking in 1.0.0-beta.22-1.

I'm not certain this is related to the original problem, but I encountered this same error in beta.22-1 when attempting to move my app component files from the angular-cli default of src/app/app.* to src/app/containers/app/app.*.

I tracked the problem to src/app/index.ts, which exports the app component. I found that the entry component (app.component#AppComponent) must be exported from here for main.ts or it goes missing during compilation. Changing this file made the error go away.

I changed src/app/index.ts from this:

export * from './app.component';
export * from './app.module';

To this:

export * from './containers/app/app.component';
export * from './app.module';

Is it possible that other reports have also placed their entry component in a location that is not exported in the same barrel as AppModule? I still think it's a little weird that this breaks the build, since AppComponent IS imported and set as the entry component in AppModule, so it ought not be pruned during build.

Correction: nixing the first line in index.ts also fixes this. Weirdly, I do not get a compilation error about an invalid import, just the Tried to find bootstrap code, but could not.… error.

I have a similar setup to @binarious. The only solution that seems to work for that scenario is the suggestion by @uitgewis to change https://github.com/angular/angular-cli/blob/master/packages/%40ngtools/webpack/src/entry_resolver.ts#L133 to pass true instead of false.

Recently I upgraded my angular-cli to the latest version to this date. I ran into the same error as OP while creating a migration-project. The project failed to install all the right dependencies and then I tried to start the server by angular-cli anyhow.

Resolution
My fix was simply to cd into the new project folder, npm install once again (which basically installed every dependency defined in package.json) and ng build, which did the trick.

Update
If you do happen to use Docker to build and serve your Angular2 application, you now have to specifically specify your container's IP address while launching your application.

ng serve --host CONTAINER_ADDRESS

@kevto rerun npm install work for me!.

I have the same issue without using --aot. Only with ng build command 😣

And the most strange thing is that in my laptop is working, but not in the server, with the same angular-cli version! 😨

My laptop (working)

angular-cli: 1.0.0-beta.22-1
node: 6.7.0
os: darwin x64

My server (not work)

angular-cli: 1.0.0-beta.22-1
node: 6.6.0
os: linux x64

Ok, my fault!! app directory was in the .gitignore and this is the reason why the server fails doing ng build hehe

My workaround for now:

// my original code
window.setTimeout(() => {
  platformBrowserDynamic().bootstrapModule(AppModule);
}, 0);

// added workaround
if (false) {
  platformBrowserDynamic().bootstrapModule(AppModule);
}

i had this problem

when move files in webstorm, it refacted with extension and this is the problem.
To solve change this:
import { AppModule } from 'app/app.module.ts';

to:
import { AppModule } from 'app/app.module';

I was in process of upgrading an app that previously used [email protected] and came across same exact error message, however, this happens when I try to run AoT version, i.e. with platformBrowser, not platformBrowserDynamic.
This can be seen on brand new angular-cli created project:
1) ng new PROJECT_NAME
2) npm install
3) ng serve -> works OK
4) ./node_modules/.bin/tsc -p ./src -> no errors
5) Edit tsconfig.js by adding:

,
  "exclude": [ "test.ts" ],
  "angularCompilerOptions": {
    "genDir": "./aot"
  }

6) ./node_modules/.bin/ngc -p ./src -> -> no errors
7) Edit main.ts to look like this:

import './polyfills.ts';
import { AppModuleNgFactory } from './aot/app/app.module.ngfactory';
import { platformBrowser } from '@angular/platform-browser';
platformBrowser().bootstrapModuleFactory( AppModuleNgFactory );

8) ng serve/build results in "Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options."

I have not been working in direct Angular web app for several months, am I missing something?

kinggolf
I have the same problem as you,Did you solve it?

@panglisen @hansl @juristr
Hi - I have not.

Just FYI: in the latest v1.0.0-beta.25 (and possibly earlier as well, but then the search was not recursive flag yet; #3708), the same error will show if more than 1 item is found.

In our case, we use conditional bootstrapping of multiple modules (a quite hacky way to implement widgets until a verdict is known for Angular angular/angular#13035), something like the nasty:

if (document.getElementsByTagName("app-root").length > 0) {
    platformBrowserDynamic().bootstrapModule(AppModule);
}
else if (document.getElementsByTagName("my-widget-one").length > 0) {
    platformBrowserDynamic().bootstrapModule(WidgetOneModule);
}

To show how many items were found, adjust @ngtools/webpack/src/entry_resolver:

console.info("Found " + bootstrap.length + " bootstrap items");
if (bootstrap.length != 1) {
    throw new Error('Tried to find bootstrap code, but could not. Specify either '
        + 'statically analyzable bootstrap code or pass in an entryModule '
        + 'to the plugins options; found ' + bootstrap.length );
}

Also note that output from that console.info line is only shown when restarting ng serve; when making changes to some main.ts without restarting ng serve then that logging is not shown. So I assume angular-cli then uses its cache (with possibly old bootstrap modules?). Just posting that here in case it helps someone.

The update on the error message suggested by @avbentem could indeed be a good option. What do you think @hansl ?

@panglisen In case this you still have an open issue, here is my take now. Apparently I have been out of loop for quite a while on angular-cli. It seems my flow in above comment is no longer appropriate. I think steps 4-8 can be dropped and simply run ng build --prod --aot. This builds the dist folder successfully. I do not know what cli command to run locally to verify this build, but when I move the files up to my server they work!!

I can confirm for me issue is now resolved on the latest beta 25.

@johnchristopherjones just in case you did not know: as for (no longer) using the "barrel" index.ts, see #3369.

I have this issue using polymer with vaadin and angular2, if I create main-polymer.ts and change the angular-cli.json to start from this file I have the error: "Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options."
I follow this tutorial: https://vaadin.com/vaadin-documentation-portlet/elements/angular2-polymer/ng-cli-webpack.html

I had the same issue when I wanted either to wait for deviceready event triggered by cordova or bootstrap the appModule immediately if running in the web.

Changing the main.ts to the following worked for me

import {enableProdMode} from '@angular/core';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {environment} from './environments/environment';
import {AppModule} from './modules/app.module';

if (environment.production) {
    enableProdMode();
}

let bootstrap = () => {
    platformBrowserDynamic().bootstrapModule(AppModule);
};

if (window.cordova) {
    document.addEventListener('deviceready', bootstrap.bind(this), false);
}
else {
    bootstrap();
}

It seems like there may only be a single call to bootstrapModule. Previously I'd the call to bootstrapModule in both places if and else branch.

It seems everybody got this to work when calling bootstrap without wrapping it. We don't wrap and still run into this issue. This is our main.ts

// import ...

if (environment.production) {
    enableProdMode();
}
const options: ToastOptions = new ToastOptions({
    toastLife: 15000,
    positionClass: 'toast-top-center',
    showCloseButton: true
});

@NgModule({
    imports     : [BrowserModule, FormsModule, HttpModule, routing, ToastModule.forRoot(options)],
    declarations: [AppComponent, COMPONENTS, ARTICLE_DND_DIRECTIVES],
    providers   : [appRouterProviders, SERVICES, ARTICLE_DND_PROVIDERS, WindowRefService,
        {provide: ErrorHandler, useClass: CustomErrorHandler}, DatePipe],
    bootstrap   : [AppComponent]
})
export class AppModule {
}

platformBrowserDynamic().bootstrapModule(AppModule);

And we get

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

using Angular CLI version 1.0.0-beta.28.3

Ok I just solved it. I cannot declare the AppModule within the same file as I do bootstrapModule. I had to put all the AppModule code in an own file and import it to the main.ts.

I have been facing the same issue when I have tried to load Module according to if statement.

const url = location.href;
if (url.indexOf('.') > -1) {
   platformBrowserDynamic().bootstrapModule(PreviewModule);
} else {
   platformBrowserDynamic().bootstrapModule(LandingModule);
}

This code could not compile with message:

Tried to find bootstrap code, but could not. Specify either statically analyzable bootstrap code or pass in an entryModule to the plugins options.

To fix this error I have made another typescript file (just as @LukasBombach explained):

import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {LandingModule} from './app/landing/landing.module';

export function bootstrapLandingModule() {
  platformBrowserDynamic().bootstrapModule(LandingModule);
}

and now main.ts look like this:

const url = location.href;
if (url.indexOf('.') > -1) {
  platformBrowserDynamic().bootstrapModule(PreviewModule);
} else {
  bootstrapLandingModule();
}

I can compile without any problems now.

ng version

@angular/cli: 1.0.0-beta.30
node: 7.5.0
os: darwin x64
@angular/common: 2.4.6
@angular/compiler: 2.4.6
@angular/core: 2.4.6
@angular/forms: 2.4.6
@angular/http: 2.4.6
@angular/material: 2.0.0-beta.1
@angular/platform-browser: 2.4.6
@angular/platform-browser-dynamic: 2.4.6
@angular/router: 3.4.6
@angular/cli: 1.0.0-beta.30
@angular/compiler-cli: 2.4.6

@criticalbh, nice workaround!

However, am I right to assume that PreviewModule extends LandingModule, hence all is fine for both usages even though Angular CLI will only have used the first as a starting point to determine what code to include in the generated bundles?

If true, then I guess that specifying that module as the entry module intsconfig.json would give you the same results, with the original code?

{
    "angularCompilerOptions": {
        "entryModule": "./app/preview/preview.module#PreviewModule",
        "genDir": "./aot"
    },
    "compilerOptions": {
        ...
    },
    ...
}

(The above solves things for me, but requires the entry module to hit all code that other modules need. In our case, ng build -prod --aot actually only needs to support the module we defined in entryModule, as the other code is just for our own use and deployed on a different server, for which we don't require the speed improvements given by AOT.)

I'm having same issue, it started when I enabled HMR feature in the Angular-cli and the BootstrapModule is not wrapped under any DOM element, my main.ts below:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { hmrBootstrap } from './hmr';

if (environment.production) {
  enableProdMode();
  platformBrowserDynamic().bootstrapModule(AppModule)
  .catch(function(err) {console.log(err)});
}

const bootstrap = () => platformBrowserDynamic().bootstrapModule(AppModule);
if (environment.hmr) {
  if (module[ 'hot' ]) {
    hmrBootstrap(module, bootstrap);
  } else {
    console.error('HMR is not enabled for webpack-dev-server!');
    console.log('Are you using the --hmr flag for ng serve?');
  }
} else {
  bootstrap();
}

any idea how to resolve this issue without revert back HRM?

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._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

MateenKadwaikar picture MateenKadwaikar  Â·  3Comments

rwillmer picture rwillmer  Â·  3Comments

hareeshav picture hareeshav  Â·  3Comments

hartjo picture hartjo  Â·  3Comments

brtnshrdr picture brtnshrdr  Â·  3Comments