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

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)

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 27
  • Comments: 41 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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

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

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

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 get this same error. If I remove the catch handler it works.

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

My workaround for now:

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

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

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

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.

I was in process of upgrading an app that previously used angular-cli@1.0.0-beta.16 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"
  }
  1. ./node_modules/.bin/ngc -p ./src -> -> no errors
  2. 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 );
  1. 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?

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);
  });
});

@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 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';

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);

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.

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.

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

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

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?

@kevto rerun npm install work for me!.

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

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.