Quali sono le differenze tra SystemJS e Webpack?


222

Sto creando la mia prima applicazione angolare e vorrei capire qual è il ruolo dei caricatori di moduli. Perché ne abbiamo bisogno? Ho provato a cercare e cercare su Google e non riesco a capire perché è necessario installarne uno per eseguire la nostra applicazione?

Non potrebbe essere sufficiente utilizzare solo importper caricare elementi dai moduli del nodo?

Ho seguito questo tutorial (che utilizza SystemJS) e mi fa usare il systemjs.config.jsfile:

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

Perché abbiamo bisogno di questo file di configurazione?
Perché abbiamo bisogno di SystemJS (o WebPack o altri)?
Infine, secondo te qual è il migliore?


4
Qui puoi leggere un ottimo articolo per confrontare SystemJs (Jspm) con Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack .
Sweta,

vedere questa risposta stackoverflow.com/a/40670147/2545680 per SystemJS
Max Koretskyi

Risposte:


135

Se vai alla pagina di SystemJS Github, vedrai la descrizione dello strumento:

Caricatore di moduli dinamici universali: carica i moduli ES6, AMD, CommonJS e script globali nel browser e NodeJS.

Poiché si utilizzano moduli in TypeScript o ES6, è necessario un caricatore di moduli. Nel caso di SystemJS, systemjs.config.jsci consente di configurare il modo in cui i nomi dei moduli sono abbinati ai loro file corrispondenti.

Questo file di configurazione (e SystemJS) è necessario se lo si utilizza esplicitamente per importare il modulo principale dell'applicazione:

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

Quando si utilizza TypeScript e si configura il compilatore per il commonjsmodulo, il compilatore crea codice che non è più basato su SystemJS. In questo esempio, il file di configurazione del compilatore dattiloscritto appare così:

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

Webpack è un bundler di moduli flessibile. Ciò significa che va oltre e non solo gestisce i moduli ma fornisce anche un modo per impacchettare la tua applicazione (file concat, uglify file, ...). Fornisce inoltre un server di sviluppo con caricamento del carico per lo sviluppo.

SystemJS e Webpack sono diversi ma con SystemJS, hai ancora del lavoro da fare ( ad esempio con Gulp o il builder SystemJS ) per impacchettare l'applicazione Angular2 per la produzione.


2
Quando dici "con SystemJS, hai ancora del lavoro da fare (con Gulp o SystemJS Builder per esempio) per impacchettare la tua applicazione Angular2 per la produzione" è quello con cui mi trovo attualmente npm start?
smartmouse

5
In effetti, per la produzione, non è efficiente caricare molti file per i moduli (singoli file (~ 300 richieste) o raggruppati (~ 40 richieste)). Devi raccogliere tutto in uno o due (il tuo codice e il codice della libreria di terze parti), compilare offline i tuoi modelli (ngc) e sfruttare l'agitazione dell'albero per ridurre al minimo il peso dei pacchetti. Questo articolo potrebbe interessarti: blog.mgechev.com/2016/06/26/… . Devi anche ugualizzare i file CSS.
Thierry Templier,

1
Con npm start, "semplicemente" avvii un server che servirà la tua applicazione in base alla configurazione di SystemJS per i moduli ...
Thierry Templier

11
Google è passato ufficialmente al webpack. Quindi credo sia meglio attenersi a ciò che la maggior parte della comunità utilizzerà. Presto migrerò il mio progetto systemJS sul webpack. Non sono del tutto sicuro di come farlo.
user2180794

1
@JonasKello è il caso del cli angolare. Vedi questo link: github.com/angular/angular-cli nella sezione "Aggiornamento Webpack"?
Thierry Templier,

190

SystemJS funziona sul lato client. Carica moduli (file) dinamicamente su richiesta quando sono necessari. Non è necessario caricare l'intera app in anticipo. È possibile caricare un file, ad esempio, all'interno di un gestore di clic sui pulsanti.

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

Oltre a configurarlo per funzionare, questo è tutto per SystemJS! Ora sei un professionista di SystemJS!

Webpack è completamente diverso e richiede un'eternità per padroneggiare. Non fa la stessa cosa di SystemJS ma, quando si utilizza Webpack, SystemJS diventa ridondante.

Webpack prepara un singolo file chiamato bundle.js: questo file contiene tutto HTML, CSS, JS, ecc. Poiché tutti i file sono raggruppati in un singolo file, ora non è necessario un caricatore pigro come SystemJS (dove i singoli file vengono caricati come necessario).

Il vantaggio di SystemJS è questo caricamento pigro. L'app dovrebbe essere caricata più velocemente perché non stai caricando tutto in un colpo solo.

Il vantaggio di Webpack è che, sebbene l'app possa richiedere alcuni secondi per caricarsi inizialmente, una volta caricata e memorizzata nella cache è velocissima.

Preferisco SystemJS ma Webpack sembra essere più trendy.

Angular2 quickstart utilizza SystemJS.

La CLI angolare utilizza Webpack.

Webpack 2 (che offrirà agitazione dell'albero) è in beta, quindi forse è un brutto momento per passare a Webpack.

Nota SystemJS sta implementando lo standard di caricamento del modulo ES6 . Webpack è solo un altro modulo npm.

Task runner (lettura facoltativa per coloro che vogliono capire l'ecosistema in cui potrebbe esistere SystemJS)

Con SystemJS la sua unica responsabilità è il caricamento lento dei file, quindi è ancora necessario qualcosa per minimizzare quei file, trascrivere quei file (ad esempio da SASS a CSS), ecc. Questi lavori che devono essere eseguiti sono noti come attività .

Webpack, quando configurato, lo fa correttamente per te (e raggruppa l'output insieme). Se si desidera fare qualcosa di simile con SystemJS, in genere si utilizza un task runner JavaScript. Il task runner più popolare è un altro modulo npm chiamato gulp .

Quindi, ad esempio, SystemJS potrebbe caricare lentamente un file JavaScript minimizzato che è stato minimizzato da gulp. Gulp, se configurato correttamente, può minimizzare i file al volo e ricaricare dal vivo. La ricarica in tempo reale è il rilevamento automatico di una modifica del codice e un aggiornamento automatico del browser per l'aggiornamento. Ottimo durante lo sviluppo. Con CSS, lo streaming live è possibile (ovvero vedi la pagina aggiornare i nuovi stili senza che la pagina venga ricaricata).

Ci sono molte altre attività che Webpack e gulp possono eseguire che sarebbero troppo numerose per essere affrontate qui. Ho fornito un esempio :)


7
Anche io trovo SystemJS e JSPM molto più facili da lavorare rispetto al webpack. Inoltre ho trovato i bundle di produzione più piccoli (rispetto ad un altro progetto di esempio di webpack). Ecco il mio post sull'argomento: stackoverflow.com/questions/40256204/…
Peter Salomonsen,

7
È possibile utilizzare Webpack e il caricamento Lazy con l'utilizzo angular2-router-loader. Vedi altro medium.com/@daviddentoom/…
Alex Klaus,

36
Ti sbagli su Webpack! Ti consente di combinare il raggruppamento con il caricamento lento. Inoltre, raggruppa in modo trasparente moduli differiti in blocchi.
dizel3d,

3
@AlexKlaus grazie per l'esempio! Stavo cercando qualcosa del genere :)
tftd

3
"Webpack è completamente diverso e richiede un'eternità da padroneggiare. Non fa la stessa cosa di SystemJS ma, quando si utilizza Webpack, SystemJS diventa ridondante." Non sono d'accordo. SystemJS consente ancora lo sviluppo di sviluppatori senza dover costantemente costruire per ogni cambiamento. Posso apportare una modifica a un file TS, salvare (che chiamerà automaticamente tsc.exe e lo costruirà), quindi ricaricare la mia pagina e non avere problemi. Con Webpack, devo ricostruire che può richiedere molto più tempo perché si ricompilerà e costruirà tutto . Non sono stato in grado di trovare alcun modo per evitarlo utilizzando Webpack.
Polantaris,

0

Finora stavo usando systemjs. Stava caricando i file uno per uno e il primo caricamento impiegava 3-4 secondi senza file minimizzati. Dopo essere passato al webpack ho ottenuto un notevole miglioramento delle prestazioni. Ora ci vuole solo per caricare un file bundle (anche polyfill e librerie dei distributori che non sono quasi mai cambiate e quasi sempre memorizzate nella cache) e il gioco è fatto. Ora ci vuole solo un secondo per caricare l'app lato client. Nessuna logica lato client aggiuntiva. Minore è il numero di singoli file caricati, maggiore è la prestazione. Quando usi systemjs dovresti pensare a importare moduli in modo dinamico per risparmiare sulle prestazioni. Con il webpack ti concentri principalmente sulla tua logica perché le prestazioni saranno ancora buone una volta che il bundle è minimizzato e memorizzato nella cache nel tuo browser.


3
Hai risposto solo a una delle domande di OP, sarebbe stato meglio fare un commento.
Ben
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.