Angular 2 Быстрый старт: неожиданный токен <

Я пытаюсь настроить angular 2 по быстрому старту, найденному в http://angular.io. Я скопировал каждый файл точно так, как описано в руководстве, но когда я запустил npm start и откроется вкладка браузера, я получаю "Загрузка..." со следующей ошибкой в ​​консоли:

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

Это мой app.component.ts:

import {Component} from 'angular2/core';

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

}

Мой boot.ts:

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

bootstrap(AppComponent);

Мой 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>

Мой 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"
    }
}

И, наконец, мой tsconfig.json:

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

Заранее благодарим за помощь.

Ответ 1

Попробуйте заменить это

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

с этим

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

Я пытался применить немного другую структуру папок к их быстрому старту и столкнулся с той же проблемой. Я обнаружил, что имя свойства в объекте "пакеты" должно соответствовать родительской папке.

Ответ 2

Совет для тех, кто сталкивается с "Неожиданным токеном <" ошибка. Для меня это произошло, когда SystemJS попытался получить зависимость (файл JavaScript), и вместо этого веб-сервер вернул HTML-страницу (отсюда неожиданное открытие < в html).

Я смог точно определить это в Chrome Dev Tools на вкладке "Сеть", просмотрев загруженные файлы JavaScript один за другим, пока не нашел тот, где вместо него был возвращен HTML. Это упростило решение проблемы с моим импортом.

Надеясь, что в какой-то момент мы можем получить более значимое сообщение об ошибке -

Ответ 3

У меня были аналогичные проблемы с различными модулями node и пришли сюда из Google.

Обычно я получаю сообщение об ошибке после import с пакетом, а затем пытаюсь его использовать.

Например, у меня была такая же проблема при загрузке https://github.com/ngrx/store.

Я проверил вкладку своей сети, и оказалось, что файл, который был загружен для store.js(этот основной файл модуля), неверен. Он запросил store.js, но получил мой index.html, который начинался с <!DOCTYPE html>, т.е. Он начинался с символа "<", который не является допустимым JavaScript.

Мне непонятно, почему мой index.html был использован вместо фактического файла JavaScript. Одно из объяснений могло бы заключаться в том, что SystemJS сделал запрос, который нигде не шел, и мой сервер был настроен на обслуживание index.html по умолчанию. Однако у меня недостаточно данных, чтобы доказать это. Cum grano salis.

В любом случае я исправил это, явно указав SystemJS, где живет пакет, если он не может найти его сам по себе. Например, чтобы исправить ошибку import { Store } from '@ngrx/store';, вы можете сделать:

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

Потому что модуль Store живет в этом файле. Таким образом SystemJS находит это, и модуль может быть импортирован просто отлично.

Ответ 4

У меня была аналогичная проблема с импортом rx.js Я решил это решить, добавив путь к System.config()

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

Ответ 5

У меня была аналогичная проблема, я настроил сервер IIS для перезаписи всех путей на index.html, чтобы обеспечить правильную работу маршрутизатора. (Обновление страницы возвращалось 404. Подробнее читайте в этом ответе)

Как указывает пользователь @dchacke, он потому, что System.js ожидает, что файл .js не является файлом .html. Это действительно вызывает странное сообщение, начинающееся с SyntaxError: Unexpected token <. Временное отключение перезаписи URL-адресов позволяет мне увидеть реальную проблему.

При импорте дочерних компонентов в родительские компоненты System.js может запутаться, если пути не объявлены должным образом.

Например, parent.component.ts имеет следующий импорт:

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

Выдает эту ошибку:

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

Изменение пути команды импорта относительно абсолютного пути решает проблему:

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

Сопоставление пути в system.config.js также может сделать трюк, но мне сложно его поддерживать, потому что неясно, почему работает путь импорта или нет. Теперь я могу раскомментировать правила перезаписи в Web.config, и все работает отлично.

Edit:

Похоже, что transpiler typescript очень разборчив в отношении путей. Только относительные пути проходят без ошибок:

В основном вам нужно сделать резервную копию одной папки из папки parentComponentFolder/ в app/.

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

Ответ 6

Я столкнулся с этой проблемой. Я исправил это, выполнив следующее в моем index.html(примечание: я помещал зависимости angular2 js в папку "lib" ):

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

Ответ 7

У меня возникла аналогичная проблема:

Unexpected token ]

При запуске сервера. Оказывается, у меня была запятая запятая в моем tsconfig.json:

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

Урок: не просто предположите, что это ошибка в исходном коде. Также проверьте свои файлы конфигурации.

Ответ 8

Конечная запятая в вашей конфигурации systemjs вызовет это.

Проверьте файл systemjs.config.ts и убедитесь, что json действителен.

Ответ 9

У меня была подобная ошибка. Я получил:

Uncaught SyntaxError: Unexpected token =  (index):16

потому что я выбрал точку с запятой в конце @Input() в файле hero-detail.component.

Надеюсь, это поможет кому-то.

Ответ 10

В моем случае я случайно включил расширение файла в import...

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

И (очевидно!) это должно было быть...

import {SomeComponent} from 'some.component';

Ответ 11

Основной причиной этой проблемы является то, что файл, который вы пытаетесь импортировать, является html файлом, а не файлом js. Вы можете увидеть это, используя вкладку сети в Chrome, чтобы просмотреть файл, который он фактически импортировал.

Моя проблема не была решена методами выше. Для меня это произошло потому, что я перенаправлял все маршруты по умолчанию на страницу index.html, так как я получаю глубокую ссылку Angular, работающую в Visual Studio Enterprise. Когда я запросил файл без расширения и не смог найти этот файл, он будет обслуживать страницу index.html по умолчанию, которая начинается с < характер и неудачу.

Дешевая распродажа для меня заключалась в том, что, когда я помещаю полный путь в точный файл, это сработает.

Во всяком случае, чтобы исправить это, мне пришлось добавить маршрут Ignore для папки node_modules в файле RouteConfig.cs:

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

}

Ответ 12

Я получил такое же сообщение об ошибке. Подобно тому, что упоминалось другими людьми, мое дело было вызвано перезаписью URL, служащей html вместо ожидаемого javascript angular.

Я использую lite-server/browser-sync для разработки и размещения моего приложения локально. Чтобы корректно работать с маршрутизацией angular, я использовал

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

перенаправить соответствующую навигацию pushState обратно в index.html. В конечном счете неправильная конфигурация в моем импортировании typescript привела к тому, что один запрос не был распознан как файл js и вместо этого перенаправлен на index.html. Трудность заключалась в том, как понять это.

Я обнаружил, что вы можете включить подробное ведение журнала для истории подключения-api-fallback.

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

который затем заставил меня найти виновника, просмотрев журнал для перенаправленных записей:

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

Ответ 13

Для тех, кто прочитал все это и не нашел ничего интересного, у меня может быть другой вариант для вас.

Я столкнулся с той же проблемой, потому что веб-сайт был развернут на более чем 1 веб-сервере. Проблема была связана с различными сборками, развернутыми на некоторых серверах.

В принципе, у вас есть 1 сервер с одной версией и другой сервер с другой версией. Итак, конечно, когда вы загружаете баланс, вы, вероятно, получите 404 на некоторых ресурсах на некоторых серверах, потому что версии разные (помните main.xxxxx.js, где xxx отличается при каждой сборке). И если вы настроили веб-сервер, чтобы вернуть страницу 404 - что случается много, я думаю - вы получаете некоторый HTML вместо JS файлов, а затем неожиданный токен.

Итак, проверьте свои версии на каждом сервере!

Ответ 14

Для меня эта ошибка была вызвана тем, что я служил в моем интерфейсе angular с помощью простого node экспресс-сервера как такового:

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

но я забыл указать, что все статические файлы должны быть отправлены из текущего каталога с линией:

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

Таким образом, каждый вызов статического актива возвращает index.html. Woops. Как только я добавил эту строку, все было в порядке. Надеюсь, это может помочь кому-то по линии:)