Jakie są różnice między SystemJS a Webpack?

222

Tworzę moją pierwszą aplikację Angular i zastanawiam się, jaka jest rola modułów ładujących. Dlaczego ich potrzebujemy? Próbowałem wyszukiwać i wyszukiwać w Google i nie rozumiem, dlaczego musimy zainstalować jeden z nich, aby uruchomić naszą aplikację?

Czy nie wystarczy po prostu użyć importdo załadowania rzeczy z modułów węzłów?

Postępowałem zgodnie z tym samouczkiem (który używa SystemJS) i sprawia, że ​​używam systemjs.config.jspliku:

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

Dlaczego potrzebujemy tego pliku konfiguracyjnego?
Dlaczego potrzebujemy SystemJS (lub WebPack lub innych)?
Wreszcie, Twoim zdaniem, co jest lepsze?

smartmouse
źródło
4
Tutaj możesz przeczytać naprawdę dobry artykuł, aby porównać SystemJs (Jspm) z pakietem Web ilikekillnerds.com/2015/07/jspm-vs-webpack .
Sweta,
zobacz tę odpowiedź stackoverflow.com/a/40670147/2545680 dla SystemJS
Max Koretskyi

Odpowiedzi:

135

Jeśli przejdziesz na stronę SystemJS Github, zobaczysz opis narzędzia:

Uniwersalny moduł ładowania dynamicznego - ładuje moduły ES6, AMD, CommonJS i globalne skrypty w przeglądarce i NodeJS.

Ponieważ używasz modułów w TypeScript lub ES6, potrzebujesz modułu ładującego. W przypadku SystemJS systemjs.config.jspozwala nam skonfigurować sposób dopasowywania nazw modułów do odpowiadających im plików.

Ten plik konfiguracyjny (i SystemJS) jest konieczny, jeśli użyjesz go jawnie do zaimportowania głównego modułu aplikacji:

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

Podczas korzystania z TypeScript i konfigurowania kompilatora do commonjsmodułu kompilator tworzy kod, który nie jest już oparty na SystemJS. W tym przykładzie plik konfiguracyjny kompilatora maszynopisu wygląda następująco:

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

Webpack to elastyczny moduł do pakowania. Oznacza to, że idzie dalej i nie tylko obsługuje moduły, ale także zapewnia sposób na spakowanie aplikacji (pliki konkat, pliki uglify, ...). Zapewnia również serwer deweloperów z przeładowaniem obciążenia w celu programowania.

SystemJS i Webpack są różne, ale w SystemJS nadal masz wiele do zrobienia ( na przykład w Gulp lub Konstruktorze SystemJS ), aby spakować aplikację Angular2 do produkcji.

Thierry Templier
źródło
2
Kiedy mówisz „z SystemJS, wciąż masz coś do zrobienia (na przykład z Gulp lub Konstruktorem SystemJS), aby spakować aplikację Angular2 do produkcji”, to z czym obecnie mam npm start?
smartmouse
5
W rzeczywistości w przypadku produkcji ładowanie wielu plików do modułów nie jest wydajne (pliki indywidualne (~ 300 żądań) lub pakiet (~ 40 żądań)). Musisz zebrać wszystko w jeden lub dwa (kod i kod biblioteki innej firmy), skompilować offline szablony (ngc) i wykorzystać wstrząsanie drzewem, aby zminimalizować wagę pakietów. Ten artykuł może Cię zainteresować: blog.mgechev.com/2016/06/26/... . Musisz także ulepszyć pliki CSS.
Thierry Templier
1
Dzięki npm start „po prostu” uruchamiasz serwer, który będzie obsługiwał twoją aplikację w oparciu o konfigurację SystemJS dla modułów ...
Thierry Templier
11
Google oficjalnie przeniósł się do pakietu internetowego. Sądzę więc, że lepiej trzymać się tego, z czego skorzystałaby większość społeczności. Wkrótce przeprowadzam migrację projektu systemJS do pakietu WWW. Nie do końca wiem, jak to zrobić.
user2180794
1
@JonasKello tak jest w przypadku kątowego CLI. Zobacz ten link: github.com/angular/angular-cli w sekcji „Aktualizacja pakietu Webpack”?
Thierry Templier
190

SystemJS działa po stronie klienta. Ładuje moduły (pliki) dynamicznie na żądanie, gdy są potrzebne. Nie musisz ładować całej aplikacji z góry. Możesz załadować plik, na przykład, w module obsługi kliknięcia przycisku.

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

Oprócz skonfigurowania go do pracy, to wszystko, co jest w SystemJS! Jesteś teraz zawodowcem SystemJS!

Webpack jest zupełnie inny i trwa wiecznie. Nie robi tego samego co SystemJS, ale podczas korzystania z pakietu WebJack SystemJS staje się zbędny.

Webpack przygotowuje pojedynczy plik o nazwie bundle.js - ten plik zawiera cały HTML, CSS, JS itp. Ponieważ wszystkie pliki są spakowane w jednym pliku, nie ma już potrzeby leniwego modułu ładującego, takiego jak SystemJS (gdzie pojedyncze pliki są ładowane jako potrzebne).

Zaletą SystemJS jest to leniwe ładowanie. Aplikacja powinna się ładować szybciej, ponieważ nie ładujesz wszystkiego za jednym razem.

Zaletą Webpacka jest to, że chociaż ładowanie aplikacji może potrwać kilka sekund, po załadowaniu i zapisaniu w pamięci podręcznej jest błyskawiczne.

Wolę SystemJS, ale Webpack wydaje się być bardziej modny.

Szybki start Angular2 wykorzystuje SystemJS.

Angular CLI korzysta z pakietu Webpack.

Webpack 2 (który oferuje wstrząsanie drzewem) jest w fazie beta, więc może to zły moment na przejście do Webpack.

Uwaga SystemJS wdraża standard ładowania modułu ES6 . Webpack to kolejny moduł npm.

Biegacze zadań (opcjonalne czytanie dla tych, którzy chcą zrozumieć ekosystem, w którym może istnieć SystemJS)

W przypadku SystemJS jego wyłączna odpowiedzialność polega na leniwym ładowaniu plików, więc nadal potrzebne jest coś, aby je zminimalizować, przenieść te pliki (np. Z SASS na CSS) itp. Te zadania, które należy wykonać, są znane jako zadania .

Webpack, jeśli jest skonfigurowany, robi to poprawnie dla ciebie (i pakuje dane wyjściowe razem). Jeśli chcesz zrobić coś podobnego z SystemJS, zwykle używasz programu uruchamiającego zadania JavaScript. Najpopularniejszym programem uruchamiającym zadania jest inny moduł npm o nazwie gulp .

Na przykład SystemJS może leniwie załadować zminimalizowany plik JavaScript, który został zminimalizowany przez gulp. Gulp, jeśli zostanie poprawnie skonfigurowany, może zminimalizować pliki w locie i przeładować na żywo. Przeładowywanie na żywo to automatyczne wykrywanie zmiany kodu i automatyczne odświeżanie przeglądarki w celu aktualizacji. Świetny podczas rozwoju. Dzięki CSS możliwe jest przesyłanie strumieniowe na żywo (tzn. Strona aktualizuje nowe style bez konieczności ponownego ładowania strony).

Istnieje wiele innych zadań, które może wykonać Webpack i gulp, których byłoby zbyt wiele, by je tutaj opisać. Podałem przykład :)

danday74
źródło
7
Ja też uważam, że SystemJS i JSPM są o wiele łatwiejsze w obsłudze niż webpack. Odkryłem również, że pakiety produkcyjne są mniejsze (w porównaniu z innym przykładowym projektem webpacka). Oto mój post na ten temat: stackoverflow.com/questions/40256204/...
Peter Salomonsen,
7
Możesz używać ładowania Webpack i Lazy za pomocą angular2-router-loader. Zobacz więcej medium.com/@daviddentoom/…
Alex Klaus
36
Mylisz się co do Webpacka! Pozwala łączyć wiązanie z leniwym ładowaniem. Ponadto w przejrzysty sposób łączy odroczone moduły w części.
dizel3d
3
@AlexKlaus dzięki za przykład! Szukałem czegoś takiego :)
tftd
3
„Webpack jest zupełnie inny i jego opanowanie trwa wiecznie. Nie robi tego samego co SystemJS, ale podczas korzystania z Webpack SystemJS staje się zbędny”. Nie mogę się zgodzić. SystemJS nadal pozwala programistom rozwijać się bez konieczności ciągłego budowania każdej zmiany. Mogę dokonać zmiany w pliku TS, zapisać (który automatycznie wywoła tsc.exe i go skompilować), a następnie ponownie załadować stronę i nie mieć żadnych problemów. Z Webpack, muszę odbudować co może znacznie dłużej brać, ponieważ będzie to skompilować i zbudować wszystko . Nie udało mi się znaleźć sposobu na uniknięcie tego przy użyciu pakietu Webpack.
Polantaris,
0

Do tej pory korzystałem z systemjs. Ładowanie plików jeden po drugim, a pierwsze ładowanie trwało 3-4 sekundy bez zminimalizowanych plików. Po przejściu na webpack otrzymałem świetną poprawę wydajności. Teraz wystarczy tylko załadować jeden plik pakietu (także polypełniania i biblioteki dostawców, które prawie nigdy się nie zmieniały i prawie zawsze są buforowane) i to wszystko. Teraz zajmuje tylko sekundę, aby załadować aplikację po stronie klienta. Brak dodatkowej logiki po stronie klienta. Im mniejsza liczba załadowanych pojedynczych plików, tym wyższa wydajność. Korzystając z systemjs, powinieneś pomyśleć o dynamicznym importowaniu modułów, aby zaoszczędzić na wydajności. W pakiecie internetowym skupiasz się głównie na logice, ponieważ wydajność będzie nadal dobra po zminimalizowaniu pakietu i zapisaniu go w pamięci podręcznej w przeglądarce.

Hrach Gyulzadyan
źródło
3
Odpowiedziałeś tylko na jedno z pytań OP, lepiej byłoby skomentować.
Ben