Je suis un débutant complet de Angular et Angular2. Je ne comprends pas comment le flux de travail est structuré. J'ai examiné le exemple de projet présent dans Angular2. site.
Corrigez-moi si je me trompe, mais ce que je sais jusqu'à présent, c'est que tout le TypeScript est transpilé en javascript par le compilateur TypeScript. Ensuite, le javascript compilé correspond à ce qui est exécuté dans le navigateur.
Maintenant, si j'importe les fichiers javascript dans TypeScript à l'aide d'instructions d'importation ES6 telles que:
import { NgModule } from '@angular/core';
Pourquoi dois-je à nouveau utiliser SystemJS pour les charger -:
map: {
// our app is within the app folder
app: 'app',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
Je veux dire, n'est-ce pas contre-productif? L'examen du javascript transcrit des fichiers ts montre que toutes les instructions d'importation sont converties en instructions require (). Premier de tous comment require () fonctionne dans un fichier js ES5 , et ensuite si tel est le cas, que fait SystemJS?.
Cela me déroute vraiment. Toute aide sera fortement appréciée.
Lorsque tsc
compile TypeScript en JavaScript, vous vous retrouvez avec un tas de fichiers js sur votre système local. Ils doivent en quelque sorte être chargés dans un navigateur. Étant donné que les navigateurs ne prennent pas encore en charge le chargement de module natif ES6, vous avez deux options: les placer toutes dans votre fichier index.html
Dans le bon ordre de dépendances ou vous pouvez utiliser un chargeur pour tout faire à votre place. Vous spécifiez la racine de tous les modules, puis tous les fichiers sont chargés et exécutés par ce chargeur dans le bon ordre de dépendances. Il existe de nombreux chargeurs: requirejs, webpack, systemjs et autres. Dans votre cas particulier, c'est systemjs.
En regardant le fichier javascript transpilé des fichiers ts, il montre que toutes les instructions d'importation sont converties en instructions require ().
Oui, c’est un moyen pour SystemJs
de charger des bundles. Il utilise la syntaxe require()
et exports
car il s'agit de la syntaxe CommonJS
pour le chargement des ensembles et vous avez spécifié ce type dans votre tsconfig.json
:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
Si vous deviez mettre module:'es6'
, Vous verriez que dans vos fichiers javascript compilés, les instructions d'importation et d'exportation sont conservées. Cependant, comme mentionné précédemment, vous ne pouvez toujours pas utiliser cette syntaxe car les navigateurs ne la prennent pas en charge de manière native. Si vous deviez mettre module:'AMD'
, Vous verriez une syntaxe différente qui utilise define()
. Je suppose que le chargeur systemjs est préféré dans le didacticiel de démarrage angular2
Car il peut charger tous les types de modules pris en charge par tsc
. Cependant, si vous voulez charger des modules en tant que modules es6
, Vous devez mettre module: 'system'
Dans votre tsconfig.json
. C'est un système de module conçu pour adhérer à la norme es6 modules
Et utilisé jusqu'à la prise en charge complète de es6 modules
Dans les navigateurs.
Comment fonctionne l'installation
Dans votre index.html
, Vous ajoutez le script suivant:
<script>
System.import('app').catch(function (err) {
console.error(err);
});
</script>
qui est exécuté lorsque index.html
est chargé. La méthode import('app')
demande à systemjs
de charger le module app
mappé au dossier app
dans la structure de répertoire de votre projet, comme spécifié par la configuration dans systemjs.config.js
:
map: {
// our app is within the app folder
app: 'app',
SystemJs recherche le fichier main.js
Dans ce dossier. Lorsque app/main.js
Est trouvé et chargé dans un navigateur, son code contient l'appel de require
:
var app_module_1 = require('./app.module');
et systemjs extrait ensuite le fichier app.module.js
du système local. Celui-ci à son tour a ses propres dépendances, comme:
var core_1 = require('@angular/core');
Et le cycle se répète - charger, rechercher des dépendances, les charger et les exécuter. Et c’est ainsi que toutes les dépendances sont résolues, chargées et exécutées dans un navigateur par le systemjs
.
Pourquoi les mappages sur les bibliothèques @angulaires principales sont requis
Dans le fichier systemjs.config.ts
, Il existe des correspondances avec les modules principaux @angular
:
map: {
...
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
'@angular/common': 'npm:@angular/common/bundles/common.umd.js',
La première chose à comprendre ici est qu’il s’agit de mappages , pas de dépendances. Cela signifie que si aucun de vos fichiers n'importe @angular/core
, Il ne sera pas chargé dans un navigateur. Cependant, vous pouvez voir que ce module particulier est importé dans app/app.module.ts
:
import { NgModule } from '@angular/core';
Maintenant, pourquoi les cartographies sont là. Supposons que systemjs
charge votre app/app.module.js
Dans le navigateur. Il analyse son contenu et trouve ce qui suit:
var core_1 = require('@angular/core');
Maintenant, systemjs
comprend qu'il doit résoudre et charger @angular/core
. Il passe d'abord par le processus de vérification de mappings
, tel que spécifié dans la documentation:
L'option map est similaire aux chemins, mais agit très tôt dans le processus de normalisation. Il vous permet de mapper un alias de module sur un emplacement ou un package.
Je l'appellerais une résolution par un module nommé. Ainsi, il trouve le mappage et substitue @angular/core
À node_modules/@angular/core
Et c’est là que sont placés les vrais fichiers.
Je pense que systemjs
tente d'imiter l'approche utilisée dans node.js
, Dans laquelle vous pouvez spécifier un module sans identificateurs de chemin relatif ['/', '../', or './']
, Simplement comme ceci require('bar.js')
et node.js
:
puis Node.js commence au répertoire parent du module actuel, ajoute/node_modules et tente de charger le module à partir de cet emplacement.
Si vous le souhaitez, vous pouvez éviter d'utiliser des mappages nommés et d'importer en utilisant un chemin relatif comme ceci:
import {NgModule} from '../node_modules/@angular/core';
Cependant, cela devrait être fait dans toutes les références à @angular.core
Dans les fichiers projet et lib, y compris @angular
, Ce qui n'est pas une bonne solution pour le moins.