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

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

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 18 (9 by maintainers)

Most upvoted comments

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

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

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.