web-dev-qa-db-fra.com

Angular2 TypeScript app génère 404 composants lorsque l'extension js n'est pas spécifiée

Je viens de commencer à jouer avec Angular2, et j'ai rencontré un problème étrange d'extension de fichier composant:

Utilisons la démo quickstart de 5 minutes de angular.io (je vais reproduire le code ici pour référence).

Structure de fichier

angular2-quickstart
|- app
|  |- app.component.ts
|  |- boot.ts
|
|- index.html
|- package.json
|- tsconfig.json

package.json

{
  "name": "angular2-quickstart",
  "version": "1.0.0",
  "scripts": {
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "lite": "lite-server",
    "start": "concurrent \"npm run tsc:w\" \"npm run lite\" "
  },
  "license": "ISC",
  "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"
  ]
}

app/app.component.ts

import {Component} from 'angular2/core';

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

app/boot.ts

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

bootstrap(AppComponent);

index.html

<html>

  <head>
    <title>Angular 2 QuickStart</title>

    <!-- 1. Load libraries -->
    <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>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        packages: {        
          app: {
            format: 'register',
            defaultExtension: 'js'
          }
        }
      });
      System.import('app/boot')
            .then(null, console.error.bind(console));
    </script>

  </head>

  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>

</html>

Cela fonctionne comme un charme, mais expose la structure de fichier entière, y compris node_modules et la configuration, ce qui semble être une mauvaise idée.

J'ai donc essayé d'exposer uniquement le dossier app. Pour y parvenir, j'ai procédé comme suit:

  • Copiez les fichiers JavaScript référencés dans un dossier app/scripts
  • Déplacer le index.html dans app
  • Changer les chemins de références dans ce fichier
  • Remplacez le script lite dans package.json par lite-server --baseDir app

Lors de l'exécution de cette opération, tout a fonctionné, sauf que angular2-polyfills.js a renvoyé: 

Error: XHR error (404 Not Found) loading http://localhost:3000/app.component(…)
  run @ angular2-polyfills.js:138
  zoneBoundFn @ angular2-polyfills.js:111
  lib$es6$promise$$internal$$tryCatch @ angular2-polyfills.js:1511
  lib$es6$promise$$internal$$invokeCallback @ angular2-polyfills.js:1523
  lib$es6$promise$$internal$$publish @ angular2-polyfills.js:1494
  lib$es6$promise$$internal$$publishRejection @ angular2-polyfills.js:1444
  (anonymous function) @ angular2-polyfills.js:243
  run @ angular2-polyfills.js:138zoneBoundFn @ angular2-polyfills.js:111
  lib$es6$promise$asap$$flush @ angular2-polyfills.js:1305

Bien sûr, si je demande http://localhost:3000/app.component.js, le fichier est renvoyé correctement.

Ma question est donc la suivante: pourquoi l'extension .js n'est-elle pas ajoutée à app.component, ce qui entraîne cette erreur, qui a fonctionné lorsque le serveur baseDir était la racine du projet? Ai-je oublié une option de configuration?

22
xlecoustillier

Vous pouvez configurer le chemin d'accès à votre dossier d'application. Dans mon cas, j'utilise angular 2 pour produire une version mobile de notre application et je devais configurer System de la manière suivante:

System.config({
            paths: {
                'app/*': './js/mobile/dist/*'
            },
            packages: {        
              app: {
                format: 'register',
                defaultExtension: 'js'
              }
            }
          });
          System.import('app/main')
                .then(null, console.error.bind(console));

Comme vous pouvez le constater, j’ai décidé de mapper "app" sur "dist", là où j’ai mes fichiers js compilés pour les conserver séparés des fichiers ts.

15
headwinds

Ce problème peut être dû à JetBrains WebStorm lors du refactoring de fichiers vers de nouveaux emplacements. Il semble ajouter l'extension .ts sur les importations.

Alors, gardez vos nouveaux fichiers à leur place, mais vérifiez les importations de chaque fichier.

Toutes vos importations doivent ressembler à ceci

import {MyComponent} from './Components/MyComponent';

Et pas ça

import {MyComponent} from './Components/MyComponent.ts';
7
Alex Hopkins

Dans mon fichier boot.ts j'ai changé cette ligne:

import {AppComponent} from './app.components'

et il fonctionne. J'ai signalé à Google aujourd'hui aussi.

4
Steven Leggett

Dans mon cas, il est résolu lorsque ajouté module.id

@Component({
    ***moduleId: module.id,***
    providers : [MyService],
    templateUrl: 'sandbox.component.html',
})
1
HydTechie

Il vous manque app/main.ts. Ce ne sont que quelques lignes, il est donc assez facile de rater le Quickstart.

0
Tyson Sukeforth

J'ai eu la même erreur avec chrome, après avoir tiré mes cheveux pendant un moment, j'ai essayé de désactiver adblock et cela a fonctionné par la suite. Si vous avez adblock, c'est probablement le coupable

0
Neel Krishna

après avoir essayé de nombreuses autres solutions suggérées par d’autres, j’ai découvert que cela peut casse par points dans les noms de fichiers et que ces deux solutions ont fonctionné pour moi.

defaultJSExtensions: true,

mais defaultJSExtensions est une propriété qui sera obsolète à l’avenir et deuxièmement:

packages: {
            '.': {
                defaultExtension: 'js'
            }
        }
0
ali-myousefi