Angular-cli: Brand new project fails to load after being built.

Created on 16 May 2016  Â·  18Comments  Â·  Source: angular/angular-cli

Please provide us with the following information:

  1. OS? Windows 7, 8 or 10. Linux (which distribution). Mac OSX (Yosemite? El Capitan?)
$ uname -a
Linux ubuntu 4.2.0-35-generic #40-Ubuntu SMP Tue Mar 15 22:15:45 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 15.10
Release:    15.10
Codename:   wily
  1. Versions. Please run ng --version. If there's nothing outputted, please
    run in a Terminal:
    node --version
    And paste the result here.
$ ng --version
Could not start watchman; falling back to NodeWatcher for file system events.
Visit http://ember-cli.com/user-guide/#watchman for more info.
angular-cli: 1.0.0-beta.2-mobile.3
node: 5.10.1
os: linux x64
  1. Repro steps. Was this an app that wasn't created using the CLI? What change did you
    do on your code? etc.
ng new test-master
cd test-master
ng build
google-grome dist/index.html

And then the errors in the console appear. :-\

  1. The log given by the failure. Normally this include a stack trace and some
    more information.

image

Most helpful comment

It has to do with being an app in HTML5 mode. For a perhaps more familiar example, think of Angular 1 in it's classic mode: urls have # symbol in them and the angular route fragments appear after that: http://www.site.com/#/route1/route2.

When your browser tries to load http://www.site.com/#/route1/route2, your server knows that #/route1/route2 is just an anchor and serves http://www.site.com/index.html.

When Angular 1 is fetching any resources it needs, it's easy to know where the app base is and thus where links are relative to: it's always http://www.site.com/ because everything else after that is just an anchor. If I need /route1/template.html I know it's in http://www.site.com/route1/template.html.

But then HTML5 mode Angular 1 appeared. It allowed us to drop the anchor and have URLs such as http://www.site.com/route1/route2, which are nicer and don't overload anchors. But just turning on HTML5 mode isn't enough. It requires two other things.

First is server rewrites. Our server needs to know that when the browser is requesting http://www.site.com/route1/route2 it should _instead_ serve http://www.site.com/index.html. In fact, index.html should be served for all routes - but never for assets. The app itself will deal with routing afterwards.

Second thing that's needed is a base tag. This is because I might be in http://www.site.com/route1/route2 and try to load an asset, /route1/template.html, and under normal circunstances this would be loaded _relative_ to the current URL, thus http://www.site.com/route1/route2/route1/template.html.

What we actually wanted was http://www.site.com/route1/template.html, so we have to tell the browser that although we are in a deep route, everything should be loaded from a certain place - usually the base domain. That's what <base href="/"> does.

To be perfectly honest I have once seen a way to dynamically determine the base tag, but it's via a script that inserts it on page load. It works, but it looks kinda dirty, and it doesn't solve the server rewrites problem anyway.

Timing is also important, because that base tag needs to be in _before_ any other load of assets - otherwise they will fail with the wrong url.

Apologies for the long explanation, but it's not a very easy topic so I don't know how to be more succinct about it.

All 18 comments

It just looks like the paths are wrong / not relative

Why not use ng serve?

because I'm trying to deploy the project.

I originally tried with ng build -e prod (according to ng --help) but that gives the same error

Try to cd dist && google-grome index.html, see if that fixes the problem. It works with lite-server on my side.

The production build is _probably_ what you want, too, if you're deploying. That mode enables bundling of every files, and will include template compilation and tree shaking when those features are available, as well as progressive template and a lot of nice features. These increase the build time by a good amount so most won't be available during dev.

@NullVoxPopuli

If you want to serve from file system, you need 2 things for making this work

  1. Start chrome with --allow-file-access-from-files argument to enable Cross origin requests for _file_ protocol scheme.
  2. Remove <base href="/"> from index.html for proper path resolution

For now you will still need to find a way to inline your stylesheets. As Angular will complain when styles are being loaded from file system

@hansl Guys your work will save us a ton of time. Many thanks!!!!!! Can't wait for complete prod build.

@hansl, @pkamdem I tried launching from the dist directory:

 google-chrome index.html --allow-file-access-from-files --new-window

however, the same errors are still there.

I opened the file in firefox, and the only error I got was just that System is not defined.

I don't think you can just simply double-click index.html from wherever. Put it on a server and you'll see it work with no errors. Don't forget to change your <base href="/"> accordingly if you put it somewhere else other than the root folder.

But maybe I'm making a mistake and not understanding what you're trying to do.

I can do this with ember CLI. :-/

I'm just wanting to test that when I deploy to thee server, everything
will work.

On Tue, May 17, 2016, 3:29 AM Ionut Achim [email protected] wrote:

I don't think you can just simply double-click index.html from wherever.
Put it on a server and you'll see it work with no errors. Don't forget to
change your accordingly if you put it somewhere else
other than the root folder.

But maybe I'm making a mistake and not understanding what you're trying to
do.

—
You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/angular/angular-cli/issues/787#issuecomment-219640262

I am able to reproduce exactly what you are trying to do, and yes, now I maintain that you can't dbl-click index.html and expect it to work, You need to serve all these files inside a webserver. You can use Vagrant or just WAMP/XAMPP/IIS to set one up locally. Or just deploy it on your server and you will see it work.

Guy who just deployed it to a server here:

"SCRIPT5009: 'System' is undefined"

Server: Windows Server 2012 R2, using IIS with nothing special. Just pointed it at the dist folder.

E: It was the base href being improper. Working now.

Would this be solved when angular-cli actually compiles all the js/templates into just a couple files, so that we don't need to make requests to render different components?

I think I can shed some light on this issue. There are a few issues at play here, and you will get different errors for each of them.

  • FILE_NOT_FOUND file:///ember-cli-live-reload.js etc: these are because of the <base href="/"> tag. Notice that it's looking for the file at the root of your file system. As @pkamdem, @monojack and @Wozbo have said, the solution is to change the tag to either point at the current directory, or <base href=""> (this last one might mess with in-app routing though).
  • System is not defined.: this error happens as a direct result of the above. SystemJS isn't loaded, thus the script tag inside of index.html that uses it will throw a var not defined error.
  • XMLHttpRequest cannot load file:///E:/path-to-app/dist/system-config.js cross origin requests... etc: this happens because chrome doesn't really like cross origin requests with the file:/// protocol. Starting chrome with the --allow-file-access-from-files flag, as was mentioned, will fix that problem.

The real cause of both of these issues is that Angular 2 and SystemJS _really_ need base paths to be correctly configured in order to be able to load all assets. This usually requires a server, so just opening your index.html file (note file instead of URL) in a browser is usually a bad idea: the file system doesn't really provide you with needed features of a server.

At the moment the CLI does compile all the js (but not templates) into bundled files, but this doesn't solve the above issues since they are base path related.

As @hansl suggested, the easiest way to test if the app works really is ng serve. If you don't want to use it, then some other server would also work, the simplest that comes to mind being http-server and doing ng build && cd dist/ && http-server && google-chrome localhost:8080. But ng serve seems simpler to me.

why should I have to specify / for the base url? is there a reason it can't be inferred like the rest of the web's static content?

It has to do with being an app in HTML5 mode. For a perhaps more familiar example, think of Angular 1 in it's classic mode: urls have # symbol in them and the angular route fragments appear after that: http://www.site.com/#/route1/route2.

When your browser tries to load http://www.site.com/#/route1/route2, your server knows that #/route1/route2 is just an anchor and serves http://www.site.com/index.html.

When Angular 1 is fetching any resources it needs, it's easy to know where the app base is and thus where links are relative to: it's always http://www.site.com/ because everything else after that is just an anchor. If I need /route1/template.html I know it's in http://www.site.com/route1/template.html.

But then HTML5 mode Angular 1 appeared. It allowed us to drop the anchor and have URLs such as http://www.site.com/route1/route2, which are nicer and don't overload anchors. But just turning on HTML5 mode isn't enough. It requires two other things.

First is server rewrites. Our server needs to know that when the browser is requesting http://www.site.com/route1/route2 it should _instead_ serve http://www.site.com/index.html. In fact, index.html should be served for all routes - but never for assets. The app itself will deal with routing afterwards.

Second thing that's needed is a base tag. This is because I might be in http://www.site.com/route1/route2 and try to load an asset, /route1/template.html, and under normal circunstances this would be loaded _relative_ to the current URL, thus http://www.site.com/route1/route2/route1/template.html.

What we actually wanted was http://www.site.com/route1/template.html, so we have to tell the browser that although we are in a deep route, everything should be loaded from a certain place - usually the base domain. That's what <base href="/"> does.

To be perfectly honest I have once seen a way to dynamically determine the base tag, but it's via a script that inserts it on page load. It works, but it looks kinda dirty, and it doesn't solve the server rewrites problem anyway.

Timing is also important, because that base tag needs to be in _before_ any other load of assets - otherwise they will fail with the wrong url.

Apologies for the long explanation, but it's not a very easy topic so I don't know how to be more succinct about it.

I have an Angular 2 app that was generated using the current version of the Angular 2 cli (as of today).

I added 2 routes using ng generate route NAME

And it runs perfectly fine using ng serve, HOWEVER when trying to build -prod and run on a server OR when trying ng serve -prod, the app loads but will not run and there are NO errors. I only see the 'loading..." text.

Any idea why? All of the paths for dependancies are correct.

@gitdisrupt can you open a new issue with exact repro steps so that I can debug?

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