Was sind die Unterschiede zwischen SystemJS und Webpack?

222

Ich erstelle meine erste Angular-Anwendung und würde herausfinden, welche Rolle die Modullader spielen. Warum brauchen wir sie? Ich habe versucht, bei Google zu suchen und zu suchen, und ich kann nicht verstehen, warum wir eine davon installieren müssen, um unsere Anwendung auszuführen.

Könnte es nicht genug sein, nur importSachen von Knotenmodulen zu laden?

Ich habe dieses Tutorial (das SystemJS verwendet) befolgt und kann systemjs.config.jsDatei verwenden:

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

Warum brauchen wir diese Konfigurationsdatei?
Warum brauchen wir SystemJS (oder WebPack oder andere)?
Was ist Ihrer Meinung nach besser?

Smartmouse
quelle
4
Hier können Sie einen wirklich guten Artikel lesen, um SystemJs (Jspm) mit Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack zu vergleichen .
Sweta
siehe diese Antwort stackoverflow.com/a/40670147/2545680 für SystemJS
Max Koretskyi

Antworten:

135

Wenn Sie zur Seite SystemJS Github gehen, wird die Beschreibung des Tools angezeigt:

Universal Dynamic Module Loader - Lädt ES6-Module, AMD, CommonJS und globale Skripte in den Browser und NodeJS.

Da Sie Module in TypeScript oder ES6 verwenden, benötigen Sie einen Modullader. Im Fall von SystemJS systemjs.config.jskönnen wir damit konfigurieren, wie Modulnamen mit den entsprechenden Dateien abgeglichen werden.

Diese Konfigurationsdatei (und SystemJS) ist erforderlich, wenn Sie sie explizit zum Importieren des Hauptmoduls Ihrer Anwendung verwenden:

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

Wenn Sie TypeScript verwenden und den Compiler für das commonjsModul konfigurieren , erstellt der Compiler Code, der nicht mehr auf SystemJS basiert. In diesem Beispiel würde die Typskript-Compiler-Konfigurationsdatei folgendermaßen aussehen:

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

Webpack ist ein flexibler Modulbündler. Dies bedeutet, dass es weiter geht und nicht nur Module verarbeitet, sondern auch eine Möglichkeit zum Packen Ihrer Anwendung bietet (Concat-Dateien, Uglify-Dateien, ...). Es bietet auch einen Entwicklungsserver mit Load Reload für die Entwicklung.

SystemJS und Webpack unterscheiden sich, aber mit SystemJS müssen Sie noch arbeiten ( z. B. mit Gulp oder SystemJS Builder ), um Ihre Angular2-Anwendung für die Produktion zu verpacken.

Thierry Templier
quelle
2
Wenn Sie sagen "Mit SystemJS haben Sie noch viel zu tun (z. B. mit Gulp oder SystemJS Builder), um Ihre Angular2-Anwendung für die Produktion zu verpacken", ist das, was ich derzeit bekomme npm start?
Smartmouse
5
Tatsächlich ist es für die Produktion nicht effizient, viele Dateien für Module zu laden (einzelne Dateien (~ 300 Anforderungen) oder gebündelt (~ 40 Anforderungen)). Sie müssen alles in einem oder zwei zusammenfassen (Ihren Code und den Bibliothekscode eines Drittanbieters), Ihre Vorlagen (ngc) offline kompilieren und das Schütteln von Bäumen nutzen, um das Gewicht von Bundles zu minimieren. Dieser Artikel könnte Sie interessieren: blog.mgechev.com/2016/06/26/… . Sie müssen auch CSS-Dateien hässlich machen.
Thierry Templier
1
Mit npm start starten Sie "einfach" einen Server, der Ihre Anwendung basierend auf Ihrer SystemJS-Konfiguration für Module bereitstellt ...
Thierry Templier
11
Google ist offiziell zu Webpack übergegangen. Ich denke, es ist besser, bei dem zu bleiben, was die Mehrheit der Community verwenden würde. Ich migriere mein systemJS-Projekt bald auf Webpack. Ich bin mir nicht ganz sicher, wie ich es machen soll.
user2180794
1
@ JonasKello das ist der Fall für eckige Cli. Siehe diesen Link: github.com/angular/angular-cli im Abschnitt "Webpack-Update"?
Thierry Templier
190

SystemJS arbeitet clientseitig. Es lädt Module (Dateien) bei Bedarf dynamisch, wenn sie benötigt werden. Sie müssen nicht die gesamte App im Voraus laden. Sie können eine Datei beispielsweise in einen Button-Click-Handler laden.

SystemJS-Code:

// 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()
});

Abgesehen davon, dass es so konfiguriert ist, dass es funktioniert, ist das alles, was SystemJS zu bieten hat! Sie sind jetzt ein SystemJS-Profi!

Webpack ist völlig anders und es dauert ewig, es zu meistern. Es funktioniert nicht wie SystemJS, aber bei Verwendung von Webpack wird SystemJS redundant.

Webpack bereitet eine einzelne Datei mit dem Namen bundle.js vor. - Diese Datei enthält alles HTML, CSS, JS usw. Da alle Dateien in einer einzigen Datei gebündelt sind, ist jetzt kein Lazy Loader wie SystemJS mehr erforderlich (wobei einzelne Dateien als geladen werden) erforderlich).

Der Vorteil von SystemJS ist das verzögerte Laden. Die App sollte schneller geladen werden, da Sie nicht alles mit einem Schlag laden.

Der Vorteil von Webpack ist, dass das Laden der App zwar einige Sekunden dauern kann, aber nach dem Laden und Zwischenspeichern blitzschnell ist.

Ich bevorzuge SystemJS, aber Webpack scheint trendiger zu sein.

Angular2-Schnellstart verwendet SystemJS.

Angular CLI verwendet Webpack.

Webpack 2 (das Baumschütteln bietet) befindet sich in der Beta-Phase. Vielleicht ist es ein schlechter Zeitpunkt, um zu Webpack zu wechseln.

Hinweis SystemJS implementiert den Ladestandard für ES6-Module . Webpack ist nur ein weiteres npm-Modul.

Aufgabenläufer (optionales Lesen für diejenigen, die das Ökosystem verstehen möchten, in dem SystemJS existieren könnte)

Bei SystemJS liegt die alleinige Verantwortung beim verzögerten Laden von Dateien, sodass noch etwas erforderlich ist, um diese Dateien zu minimieren, diese Dateien zu transpilieren (z. B. von SASS zu CSS) usw. Diese Aufgaben, die ausgeführt werden müssen, werden als Aufgaben bezeichnet .

Wenn Webpack konfiguriert ist, erledigt es dies korrekt für Sie (und bündelt die Ausgabe zusammen). Wenn Sie mit SystemJS etwas Ähnliches tun möchten, verwenden Sie normalerweise einen JavaScript-Task-Runner. Der beliebteste Task-Runner ist ein weiteres npm-Modul namens gulp .

So kann beispielsweise SystemJS eine minimierte JavaScript-Datei, die von gulp minimiert wurde, verzögert laden. Bei korrekter Einrichtung kann Gulp Dateien im laufenden Betrieb minimieren und live neu laden. Live-Reload ist die automatische Erkennung einer Codeänderung und eine automatische Aktualisierung des Browsers zum Aktualisieren. Großartig während der Entwicklung. Mit CSS ist Live-Streaming möglich (dh Sie sehen, dass die Seite die neuen Stile aktualisiert, ohne dass die Seite neu geladen wird).

Es gibt viele andere Aufgaben, die Webpack und gulp ausführen können, die zu zahlreich wären, um sie hier abzudecken. Ich habe ein Beispiel gegeben :)

danday74
quelle
7
Auch ich finde es viel einfacher, mit SystemJS und JSPM zu arbeiten als mit Webpack. Außerdem fand ich die Produktionspakete kleiner (im Vergleich zu einem anderen Webpack-Beispielprojekt). Hier ist mein Beitrag zum Thema: stackoverflow.com/questions/40256204/…
Peter Salomonsen
7
Sie können Webpack & Lazy Loading mit using verwenden angular2-router-loader. Siehe mehr medium.com/@daviddentoom/…
Alex Klaus
36
Du liegst falsch in Bezug auf Webpack! Sie können die Bündelung mit dem verzögerten Laden kombinieren. Darüber hinaus werden verzögerte Module transparent in Blöcke gebündelt.
dizel3d
3
@AlexKlaus danke für das Beispiel! Ich habe nach so etwas gesucht :)
22.
3
"Webpack ist völlig anders und es dauert ewig, bis es gemeistert ist. Es funktioniert nicht wie SystemJS, aber bei Verwendung von Webpack wird SystemJS redundant." Ich muss nicht zustimmen. SystemJS ermöglicht weiterhin die Entwicklung von Entwicklern, ohne ständig für jede Änderung bauen zu müssen. Ich kann eine TS-Datei ändern, speichern (wodurch tsc.exe automatisch aufgerufen und erstellt wird), dann meine Seite neu laden und habe keine Probleme. Mit Webpack muss ich neu erstellen, was erheblich länger dauern kann, da alles neu kompiliert und erstellt wird . Ich konnte mit Webpack keinen Weg finden, dies zu vermeiden.
Polantaris
0

Bisher habe ich systemjs verwendet. Es wurden Dateien nacheinander geladen und das erste Laden dauerte 3-4 Sekunden ohne minimierte Dateien. Nach dem Wechsel zum Webpack habe ich eine große Leistungsverbesserung erzielt. Jetzt muss nur noch eine Bundle-Datei geladen werden (auch Polyfills und Vendor-Bibliotheken, die sich fast nie geändert und fast immer zwischengespeichert haben) und fertig. Jetzt dauert das Laden der clientseitigen App nur noch eine Sekunde. Keine zusätzliche clientseitige Logik. Je weniger einzelne Dateien geladen werden, desto höher ist die Leistung. Wenn Sie systemjs verwenden, sollten Sie darüber nachdenken, Module dynamisch zu importieren, um Leistung zu sparen. Mit Webpack konzentrieren Sie sich hauptsächlich auf Ihre Logik, da die Leistung auch dann noch gut ist, wenn das Bundle minimiert und in Ihrem Browser zwischengespeichert wird.

Hrach Gyulzadyan
quelle
3
Sie haben nur eine der Fragen von OP beantwortet. Es wäre besser gewesen, einen Kommentar abzugeben.
Ben