Quelles sont les différences entre SystemJS et Webpack?

222

Je crée ma première application angulaire et je devrais comprendre quel est le rôle des chargeurs de modules. Pourquoi en avons-nous besoin? J'ai essayé de rechercher et de rechercher sur Google et je ne comprends pas pourquoi nous devons installer l'un d'eux pour exécuter notre application?

Ne serait-il pas suffisant d'utiliser simplement importpour charger des éléments à partir de modules de nœuds?

J'ai suivi ce tutoriel (qui utilise SystemJS) et cela me fait utiliser un systemjs.config.jsfichier:

/**
 * System configuration for Angular samples
 * Adjust as necessary for your application needs.
 */
(function(global) {
  // map tells the System loader where to look for things
  var map = {
    'app':                        'transpiled', // 'dist',
    '@angular':                   'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs':                       'node_modules/rxjs'
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
  };
  var ngPackageNames = [
    'common',
    'compiler',
    'core',
    'forms',
    'http',
    'platform-browser',
    'platform-browser-dynamic',
    'router',
    'router-deprecated',
    'upgrade',
  ];
  // Individual files (~300 requests):
  function packIndex(pkgName) {
    packages['@angular/'+pkgName] = { main: 'index.js', defaultExtension: 'js' };
  }
  // Bundled (~40 requests):
  function packUmd(pkgName) {
    packages['@angular/'+pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
  }
  // Most environments should use UMD; some (Karma) need the individual index files
  var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
  // Add package entries for angular packages
  ngPackageNames.forEach(setPackageConfig);
  var config = {
    map: map,
    packages: packages
  };
  System.config(config);
})(this);

Pourquoi avons-nous besoin de ce fichier de configuration?
Pourquoi avons-nous besoin de SystemJS (ou WebPack ou autres)?
Enfin, à votre avis, quoi de mieux?

smartmouse
la source
4
Ici, vous pouvez lire un très bon article pour comparer SystemJs (Jspm) avec Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack .
Sweta
voir cette réponse stackoverflow.com/a/40670147/2545680 pour SystemJS
Max Koretskyi

Réponses:

135

Si vous allez sur la page SystemJS Github, vous verrez la description de l'outil:

Chargeur de module dynamique universel - charge les modules ES6, AMD, CommonJS et les scripts globaux dans le navigateur et NodeJS.

Étant donné que vous utilisez des modules dans TypeScript ou ES6, vous avez besoin d'un chargeur de modules. Dans le cas de SystemJS, le systemjs.config.jsnous permet de configurer la façon dont les noms de module sont mis en correspondance avec leurs fichiers correspondants.

Ce fichier de configuration (et SystemJS) est nécessaire si vous l'utilisez explicitement pour importer le module principal de votre application:

<script>
  System.import('app').catch(function(err){ console.error(err); });
</script>

Lors de l'utilisation de TypeScript et de la configuration du compilateur sur le commonjsmodule, le compilateur crée du code qui n'est plus basé sur SystemJS. Dans cet exemple, le fichier de configuration du compilateur typescript apparaît comme ceci:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs", // <------
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

Webpack est un groupeur de modules flexible. Cela signifie qu'il va plus loin et ne gère pas seulement les modules mais fournit également un moyen de conditionner votre application (fichiers concat, fichiers uglify, ...). Il fournit également un serveur de développement avec rechargement de charge pour le développement.

SystemJS et Webpack sont différents mais avec SystemJS, vous avez encore du travail à faire (avec Gulp ou SystemJS builder par exemple) pour empaqueter votre application Angular2 pour la production.

Thierry Templier
la source
2
Lorsque vous dites "avec SystemJS, vous avez encore du travail à faire (avec Gulp ou le constructeur SystemJS par exemple) pour empaqueter votre application Angular2 pour la production", c'est ce que je fais actuellement avec npm start?
smartmouse
5
En fait, pour la production, il n'est pas efficace de charger un grand nombre de fichiers pour les modules (fichiers individuels (~ 300 requêtes) ou groupés (~ 40 requêtes)). Vous devez tout rassembler en un ou deux (votre code et le code de bibliothèque tiers), compiler hors ligne vos modèles (ngc) et tirer parti de l'agitation de l'arborescence pour minimiser le poids des bundles. Cet article pourrait vous intéresser: blog.mgechev.com/2016/06/26/… . Vous devez également uglifier les fichiers CSS.
Thierry Templier
1
Avec npm start, vous démarrez "simplement" un serveur qui servira votre application en fonction de votre configuration SystemJS pour les modules ...
Thierry Templier
11
Google est officiellement passé au webpack. Je suppose donc qu'il vaut mieux s'en tenir à la majorité de la communauté qui utiliserait. Je migre bientôt mon projet systemJS vers webpack. Je ne sais pas vraiment comment le faire.
user2180794
1
@JonasKello c'est le cas pour le cli angulaire. Voir ce lien: github.com/angular/angular-cli dans la section "Mise à jour du Webpack"?
Thierry Templier
190

SystemJS fonctionne côté client. Il charge les modules (fichiers) dynamiquement à la demande lorsqu'ils sont nécessaires. Vous n'avez pas besoin de charger toute l'application à l'avance. Vous pouvez charger un fichier, par exemple, à l'intérieur d'un gestionnaire de clic de bouton.

Code SystemJS:

// example import at top of file
import myModule from 'my-module'
myModule.doSomething()

// example dynamic import (could be placed anywhere in your code)
// module not loaded until code is hit
System.import('my-module').then((myModule) {
  // myModule is available here
  myModule.doSomething()
});

À part le configurer pour fonctionner, c'est tout ce qu'il y a à SystemJS! Vous êtes maintenant un SystemJS pro!

Webpack est entièrement différent et prend une éternité à maîtriser. Il ne fait pas la même chose que SystemJS mais, lors de l'utilisation de Webpack, SystemJS devient redondant.

Webpack prépare un fichier unique appelé bundle.js - Ce fichier contient tous les codes HTML, CSS, JS, etc. Étant donné que tous les fichiers sont regroupés dans un seul fichier, il n'est désormais plus nécessaire d'utiliser un chargeur paresseux comme SystemJS (où les fichiers individuels sont chargés en tant que nécessaire).

L'avantage de SystemJS est ce chargement paresseux. L'application devrait se charger plus rapidement car vous ne chargez pas tout en une seule fois.

L'avantage de Webpack est que, bien que l'application puisse prendre quelques secondes à charger initialement, une fois chargée et mise en cache, elle est ultra-rapide.

Je préfère SystemJS mais Webpack semble être plus tendance.

Le démarrage rapide d'Angular2 utilise SystemJS.

La CLI angulaire utilise Webpack.

Webpack 2 (qui offrira des tremblements d'arbre) est en version bêta, donc c'est peut-être un mauvais moment pour passer à Webpack.

Remarque SystemJS implémente la norme de chargement du module ES6 . Webpack est juste un autre module npm.

Lecteurs de tâches (lecture facultative pour ceux qui veulent comprendre l'écosystème dans lequel SystemJS pourrait exister)

Avec SystemJS, sa seule responsabilité est le chargement paresseux de fichiers, donc quelque chose est encore nécessaire pour minimiser ces fichiers, les transpiler (par exemple de SASS à CSS), etc. Ces travaux qui doivent être effectués sont appelés tâches .

Webpack, une fois configuré, le fait correctement pour vous (et regroupe la sortie). Si vous voulez faire quelque chose de similaire avec SystemJS, vous utilisez généralement un exécuteur de tâches JavaScript. Le gestionnaire de tâches le plus populaire est un autre module npm appelé gulp .

Ainsi, par exemple, SystemJS peut paresseusement charger un fichier JavaScript minifié qui a été minifié par gulp. Gulp, lorsqu'il est correctement configuré, peut réduire les fichiers à la volée et recharger en direct. Le rechargement en direct est la détection automatique d'un changement de code et une actualisation automatique du navigateur pour la mise à jour. Idéal pendant le développement. Avec CSS, la diffusion en direct est possible (c'est-à-dire que vous voyez la page mettre à jour les nouveaux styles sans même recharger la page).

Il existe de nombreuses autres tâches que Webpack et gulp peuvent effectuer et qui seraient trop nombreuses pour être couvertes ici. J'ai fourni un exemple :)

danday74
la source
7
Moi aussi, je trouve SystemJS et JSPM beaucoup plus faciles à utiliser que webpack. J'ai également trouvé que les bundles de production étaient plus petits (par rapport à un autre projet d'exemple de webpack). Voici mon article sur le sujet: stackoverflow.com/questions/40256204/…
Peter Salomonsen
7
Vous pouvez utiliser Webpack & Lazy loading avec using angular2-router-loader. Voir plus medium.com/@daviddentoom/…
Alex Klaus
36
Vous vous trompez sur Webpack! Il vous permet de combiner le regroupement avec le chargement paresseux. De plus, il regroupe de manière transparente les modules différés en morceaux.
dizel3d
3
@AlexKlaus merci pour l'exemple! Je cherchais quelque chose comme ça :)
tftd
3
"Webpack est entièrement différent et prend une éternité à maîtriser. Il ne fait pas la même chose que SystemJS mais, lors de l'utilisation de Webpack, SystemJS devient redondant." Je dois être en désaccord. SystemJS permet toujours le développement de développeurs sans avoir à constamment construire pour chaque changement. Je peux apporter une modification à un fichier TS, enregistrer (qui appellera automatiquement tsc.exe et le construira), puis recharger ma page et ne rencontrer aucun problème. Avec Webpack, je dois reconstruire ce qui peut prendre beaucoup plus de temps car il va recompiler et tout construire . Je n'ai trouvé aucun moyen d'éviter cela en utilisant Webpack.
Polantaris
0

Jusqu'à présent, j'utilisais systemjs. Il chargeait les fichiers un par un et le premier chargement prenait 3-4 secondes sans fichiers minifiés. Après être passé à webpack, j'ai obtenu une grande amélioration des performances. Maintenant, il ne suffit que de charger un fichier de bundle (également des polyfills et des bibliothèques de fournisseurs qui n'ont presque jamais changé et presque toujours mis en cache) et c'est tout. Maintenant, il ne faut plus qu'une seconde pour charger l'application côté client. Aucune logique côté client supplémentaire. Moins le nombre de fichiers individuels chargés augmente les performances. Lorsque vous utilisez systemjs, vous devez penser à importer des modules dynamiquement pour économiser les performances. Avec webpack, vous vous concentrez principalement sur votre logique car les performances seront toujours bonnes une fois que le bundle sera minimisé et mis en cache dans votre navigateur.

Hrach Gyulzadyan
la source
3
Vous n'avez répondu qu'à l'une des questions d'OP, il aurait mieux valu faire un commentaire.
Ben