Angular 2 Quickstart: unexpected token <

JavascriptAngular

Javascript Problem Overview


I am trying to set up angular 2 according the quickstart found at http://angular.io. I have copied every file exactly as described in the guide, but when I run npm start and a browser tab opens, I get the "Loading..." with the following error in the console:

Uncaught SyntaxError: Unexpected token <                        (program):1
     __exec @ system.src.js:1374
Uncaught SyntaxError: Unexpected token <          angular2-polyfills.js:138
	Evaluating http://localhost:3000/app/boot
    Error loading http://localhost:3000/app/boot

This is my app.component.ts:

import {Component} from 'angular2/core';

@Component({
	selector: 'my-app',
	template: `<h1>My First Angular 2 App</h1>`
})
export class AppComponent {

}

My boot.ts:

import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent);

My index.html:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Angular 2 Quick Start</title>

	<script src="node_modules/es6-shim/es6-shim.js"></script>
	<script src="node_modules/angular2/bundles/angular2-polyfills.js"></script>
	<script src="node_modules/systemjs/dist/system.src.js"></script>
	<script src="node_modules/rxjs/bundles/Rx.js"></script>
	<script src="node_modules/angular2/bundles/angular2.dev.js"></script>

	<script>
	System.config({
		packages: {
			format: 'register',
			defaultExtension: 'js'
		}
	});

	System.import('app/boot')
		.then(null, console.error.bind(console));
	</script>
</head>
<body>
	<my-app>Loading...</my-app>
</body>
</html>

My package.json:

{
	"name": "angular2-quickstart",
	"version": "0.1.0",
	"scripts": {
		"tsc": "tsc",
		"tsc:w": "tsc -w",
		"lite": "lite-server",
		"start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
	},
	"license": "MIT",
	"dependencies": {
		"angular2": "2.0.0-beta.0",
    	"systemjs": "0.19.6",
    	"es6-promise": "^3.0.2",
    	"es6-shim": "^0.33.3",
    	"reflect-metadata": "0.1.2",
    	"rxjs": "5.0.0-beta.0",
    	"zone.js": "0.5.10"
	},
	"devDependencies": {
		"concurrently": "^1.0.0",
	    "lite-server": "^1.3.1",
	    "typescript": "^1.7.3"
	}
}

And finally my tsconfig.json:

{
	"compilerOptions": {
		"target": "ES5",
		"module": "system",
		"moduleResolution": "node",
		"sourceMap": true,
		"emitDecoratorMetadata": true,
		"experimentalDecorators": true,
		"removeComments": false,
		"noImplicitAny": false
	},
	"exclude": [
		"node_modules"
	]
}

Thanks in advance for any help.

Javascript Solutions


Solution 1 - Javascript

Try replacing this

System.config({
        packages: {
            format: 'register',
            defaultExtension: 'js'
        }
    });

with this

System.config({
        packages: {
            app: { // must match your folder name
                format: 'register',
                defaultExtension: 'js'
            }
        }
    });

I was trying to apply a slightly different folder structure to their quickstart and ran into the same issue. I found that the name of the property on the "packages" object had to match the parent folder.

Solution 2 - Javascript

A tip for those who encounter the "Unexpected token <" error. For me, this happened when SystemJS attempted to retrieve a dependency (JavaScript file) and instead the web server returned an HTML page (hence the unexpected opening < in the html).

I was able to pinpoint this in Chrome's Dev Tools on the Network tab by looking through the downloaded JavaScript files one-by-one until I found the one where HTML was returned instead. This made it easy to resolve the issue with my import.

Hoping we may get a more meaningful error message at some point-

Solution 3 - Javascript

I've had similar issues with different node modules and came here from Google.

Usually, I would get the error after importing a package and then attempting to use it.

For example, I had the same issue when loading https://github.com/ngrx/store.

I checked my network tab and it turns out the file that was loaded for store.js (that module's main file) was not correct. It requested store.js, but got my index.html, which started with <!DOCTYPE html>, i.e. it started with a "<", which is not valid JavaScript.

It is not clear to me why my index.html was served in lieu of the actual JavaScript file. One explanation could be that SystemJS made a request that led nowhere and my server was configured to serve index.html as a default. I don't have enough data to prove this, though. Cum grano salis.

In any case, I fixed it by explicitly telling SystemJS where a package lives if it can't find it on its own. So, for example, to fix a failing import { Store } from '@ngrx/store';, you can do:

System.config({
  packages: {
    src: {
      format: 'register',
      defaultExtension: 'js'
    }
  },
  map: { '@ngrx/store' : '/node_modules/@ngrx/store/dist/store.js' } // <-- this!
});
System.import('src/boot')
      .then(null, console.error.bind(console));

Because the Store module lives in that file. This way, SystemJS finds it, and the module can be imported just fine.

Solution 4 - Javascript

I had a similar issue importing rx.js I ended up solving it by adding a path to the System.config()

System.config({
  defaultJSExtensions: true,
  paths: {
    'rx' : 'lib/rx.js'
  }
});

Solution 5 - Javascript

I had a similar issue, I had configured the IIS server to rewrite all paths to index.html in order to get the router working properly. (Page refresh was returning 404. Read details in this answer)

As user @dchacke points out, it's because System.js expects a .js file not a .html file. This indeed produces the strange message starting with SyntaxError: Unexpected token <. Temporarely disabling the URL rewriting allows me to see the real issue.

When importing child components into parent components System.js can get confused if paths are not declared properly.

For example parent.component.ts has the following import:

import { ChildComponent } from './childComponentFolder/childComponent';

Throws this error:

GET app/parentComponentFolder/childComponentFolder/childComponent.js 404 (Not Found)
Error: Error: XHR error (404 Not Found) loading app/parentComponentFolder/childComponentFolder/childComponent.js

Changing the import instruction path from relative to absolute path solves the issue:

import { ChildComponent } from 'app/childComponentFolder/childComponent';

Mapping the path in system.config.js could also do the trick, but I find it harder to maintain because it's not readily apparent why the import path works or not. Now I can uncomment the rewrite rules in Web.config and all works just fine.

Edit:

It seems that typescript transpiler is very picky about paths. Only relative paths pass without throwing errors:

Basically you need to step back up one folder from parentComponentFolder/ to app/ folder.

import { ChildComponent } from '../childComponentFolder/childComponent';

Solution 6 - Javascript

I ran into this same problem. I fixed it by implementing the following in my index.html (note: I put the angular2 js dependencies in 'lib' folder):

<html>

<head>
    <title>Desktop main</title>
</head>
<body>
<div>
    <my-app>Loading...</my-app>
</div>
   
    <script src="~/lib/anguar2/angular2-polyfills.js"></script>
    <script src="~/lib/es6-shim/es6-shim.js"></script>
    <script src="~/lib/systemjs/system.src.js"></script>
    <script>

    System.config({
        defaultJSExtensions: true

    });

    </script>
    <script src="~/lib/rxjs/rx.js"></script>
    <script src="~/lib/anguar2/angular2.dev.js"></script>
    <script>
    System.import('app/boot');
    </script>
</body>

</html>

app.component.ts looks like this:

import {Component} from "angular2/core";

@Component({
    selector: "my-app",
    template: "<h1>Hello Angular 2</h1>"
})
export class AppDesktopComponent {
    
    
}

Wish I could tell you why this works and the angular2 quickstart boilerplate doesn't.

Solution 7 - Javascript

I was getting a similar problem:

Unexpected token ]

When starting the server. Turns out I had a trailing comma in my tsconfig.json:

...
  "files": [
    "app.ts",
    "typings.d.ts",
    "abc-vt/abc-vt",   <-Doh!
  ]

Lesson: Don't just assume it's an error in your source code -- check your config files as well.

Solution 8 - Javascript

In my case, I'd inadvertently included the file extension on the import...

import {SomeComponent} from 'some.component.ts';

And (obviously!) it should have been...

import {SomeComponent} from 'some.component';

Solution 9 - Javascript

A trailing comma in your systemjs configuration will cause this.

Check the systemjs.config.ts file and make sure the json is valid.

Solution 10 - Javascript

I had a similar bug. I got:

Uncaught SyntaxError: Unexpected token =  (index):16

because I tossed a semicolon at the end of the @Input() in the hero-detail.component file.

Hope this helps somebody.

Solution 11 - Javascript

The primary cause of this issue is that the file you are trying to import is an html file, not a js file. You can see this by using the network tab in Chrome to have a look at the file it actually imported.

My issue wasn't solved by the methods above. For me, this happened because I had routed all default routes through to the index.html page, which is how I get Angular deep linking working in Visual Studio Enterprise. When I requested a file without the extension, and it couldn't find that file, it would serve the default index.html page, which would start with a < character, and fail.

The giveaway for me was that when I put the full path to the exact file, it would work.

Anyhow, to fix this, I had to add an Ignore route for the node_modules folder in my RouteConfig.cs file:

public static void RegisterRoutes(RouteCollection routes)
{
   routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
   routes.IgnoreRoute("node_modules/{*pathInfo}");

}

Solution 12 - Javascript

I had received the same error message. Similar to what other people mentioned, my case was caused by url rewrites, serving the html instead of the javascript expected by angular.

I am using lite-server/browser-sync to develop and host my app locally. To get the angular routing working properly, I was using

var history = require('connect-history-api-fallback')

to redirect relevant pushState navigation back to index.html. Ultimately, a misconfiguration in my typescript imports led to one request not being recognised as a js file and instead redirected to index.html. The difficulty was how to figure it out.

I found that you can enable verbose logging for the connect-history-api-fallback.

 middleware: [history({
        index: '/src/index.html',
        verbose: true
    })]

which then led me to find the culprit by scanning the log for redirected entries:

Not rewriting GET /node_modules/systemjs/dist/system.js because the path includes a dot (.) character.
Not rewriting GET /node_modules/core-js/client/shim.min.js because the path includes a dot (.) character.
Rewriting GET /src/culprit to /src/index.html

Solution 13 - Javascript

For those who read the whole thing and didn't found anything interesting, I may have another option for you.

I ran into the same problem because the website was deployed on more than 1 web server. The problem was related to different builds deployed on some servers.

Basically, you have 1 server with one version and another server with some other version. So, of course when you load balance you're likely to get 404 on some resources on some servers because the versions are different (remember the main.xxxxx.js where xxx is different at every build). And if you configured your webserver to return a 404 webpage

  • which happens a lot I guess - you get some HTML instead of the JS files then the unexpected token.

So, check your versions on each server !

Solution 14 - Javascript

For me, this error was caused because I served my angular frontend with a simple node express server as such:

app.use('/*', (req, res) => {
    res.sendFile(path.join(__dirname,'index.html'));
});

but I had forgotten to specify that all static files should be served from the current directory with the line:

app.use(express.static(__dirname));

So every call for a static asset returned index.html. Woops. Once I added that line, everything was fine. Hope this can help someone down the line :)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionmuukView Question on Stackoverflow
Solution 1 - JavascriptIsaacView Answer on Stackoverflow
Solution 2 - JavascriptBen WellsView Answer on Stackoverflow
Solution 3 - JavascriptweltschmerzView Answer on Stackoverflow
Solution 4 - JavascriptJRulleView Answer on Stackoverflow
Solution 5 - JavascriptAdrian MoisaView Answer on Stackoverflow
Solution 6 - JavascriptbrandoView Answer on Stackoverflow
Solution 7 - Javascriptvt5491View Answer on Stackoverflow
Solution 8 - JavascriptSteve SView Answer on Stackoverflow
Solution 9 - JavascriptjdewitView Answer on Stackoverflow
Solution 10 - JavascriptNayfinView Answer on Stackoverflow
Solution 11 - JavascripttoneView Answer on Stackoverflow
Solution 12 - JavascriptBenView Answer on Stackoverflow
Solution 13 - Javascriptvivien.destpernView Answer on Stackoverflow
Solution 14 - JavascriptMyrionSC2View Answer on Stackoverflow