What are differences between SystemJS and Webpack?
Asked Answered
E

3

236

I'm creating my first Angular application and I would figure out what is the role of the module loaders. Why we need them? I tried to search and search on Google and I can't understand why we need to install one of them to run our application?

Couldn't it be enough to just use import to load stuff from node modules?

I have followed this tutorial (that uses SystemJS) and it makes me to use systemjs.config.js file:

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

Why we need this configuration file?
Why we need SystemJS (or WebPack or others)?
Finally, in your opinion what is the better?

Every answered 8/7, 2016 at 9:36 Comment(2)
Here you can read really good article to compare SystemJs(Jspm) with Webpack ilikekillnerds.com/2015/07/jspm-vs-webpack.Sato
see this answer https://mcmap.net/q/119573/-what-is-the-need-for-systemjs-in-angular2 for SystemJSLightfingered
G
146

If you go to the SystemJS Github page, you will see the description of the tool:

Universal dynamic module loader - loads ES6 modules, AMD, CommonJS and global scripts in the browser and NodeJS.

Because you use modules in TypeScript or ES6, you need a module loader. In the case of SystemJS, the systemjs.config.js allows us to configure the way in which module names are matched with their corresponding files.

This configuration file (and SystemJS) is necessary if you explicitly use it to import the main module of your application:

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

When using TypeScript, and configuring the compiler to the commonjs module, the compiler creates code that is no longer based on SystemJS. In this example, the typescript compiler config file would appear like this:

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

Webpack is a flexible module bundler. This means that it goes further and doesn't only handle modules but also provides a way to package your application (concat files, uglify files, ...). It also provides a dev server with load reload for development.

SystemJS and Webpack are different but with SystemJS, you still have work to do (with Gulp or SystemJS builder for example) to package your Angular2 application for production.

Galenism answered 8/7, 2016 at 9:46 Comment(10)
When you say "with SystemJS, you still have work to do (with Gulp or SystemJS builder for example) to package your Angular2 application for production" is what i currently get with with npm start?Every
In fact, for production, it's not efficient to load a lot of files for modules (Individual files (~300 requests) or Bundled (~40 requests)). You need to gather everything into one or two (your code and third-party library code), compile offline your templates (ngc) and leverage tree shaking to minimize the weight of bundles. This article could interest you: blog.mgechev.com/2016/06/26/…. You also need to uglify CSS files.Galenism
With npm start, you "simply" start a server that will serve your application based on your SystemJS configuration for modules...Galenism
so basically u r saying webpack is better to go with angular 2?Back
Google has officially moved to webpack. So I guess it's better to stick with what majority of the community would be using. I am migrating my systemJS project to webpack soon. Not entirely sure how to do it though.Branchia
@Branchia Do you have a link to this offical announcement?Atomizer
@JonasKello that's the case for angular cli. See this link: github.com/angular/angular-cli in the section "Webpack update"?Galenism
You are saying "When using TypeScript, and configuring the compiler to the commonjs module, the compiler creates code that is no longer based on SystemJS" why its not based on systemjs as systemjs is universal module loader it shouldn't make any difference between node modules or commonjs module to loadMorley
Might be a bit late for my comment, but I would say that WebPack is much more flegged out, even thought it takes much more configuration than systemjs does, it seems more flexible.Pontine
wrote an article about how to migrate from systemjs/jspm to webpack. And explain why jspm + systemjs are so slow in compare with webpack alfilatov.com/posts/…Kelcy
C
216

SystemJS works client side. It loads modules (files) dynamically on demand when they are needed. You don't have to load the entire app up front. You could load a file, for example, inside a button click handler.

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

Other than configuring it to work, that's all there is to SystemJS! You are now a SystemJS pro!

Webpack is entirely different and takes forever to master. It does not do the same thing as SystemJS but, when using Webpack, SystemJS becomes redundant.

Webpack prepares a single file called bundle.js - This file contains all HTML, CSS, JS, etc. Because all files are bundled in a single file, there is now no need for a lazy loader like SystemJS (where individual files are loaded as needed).

The upside of SystemJS is this lazy loading. The app should load faster because you are not loading everything in one hit.

The upside of Webpack is that, although the app may take a few seconds to load initially, once loaded and cached it is lightning fast.

I prefer SystemJS but Webpack seems to be trendier.

Angular2 quickstart uses SystemJS.

Angular CLI uses Webpack.

Webpack 2 (which will offer tree shaking) is in beta so maybe it's a bad time to move to Webpack.

Note SystemJS is implementing the ES6 module loading standard. Webpack is just another npm module.

Task runners (optional reading for those who want to understand the ecosystem in which SystemJS might exist)

With SystemJS its sole responsibility is the lazy loading of files so something is still needed to minify those files, transpile those files (e.g. from SASS to CSS), etc. These jobs that must be done are known as tasks.

Webpack, when configured, correctly does this for you (and bundles the output together). If you want to do something similar with SystemJS you would typically use a JavaScript task runner. The most popular task runner is another npm module called gulp.

So, for example, SystemJS might lazy load a minified JavaScript file that has been minified by gulp. Gulp, when setup correctly, can minify files on the fly and live reload. Live reloading is the automatic detection of a code change and an automatic browser refresh to update. Great during development. With CSS, live streaming is possible (i.e. you see the page update the new styles without the page even reloading).

There are many other tasks which Webpack and gulp can perform which would be too numerous to cover here. I've provided an example :)

Cambridge answered 27/10, 2016 at 16:43 Comment(7)
Me too I find SystemJS and JSPM much easier to work with than webpack. Also I found the production bundles to be smaller ( compared with another webpack example project ). Here's my post about the topic: #40256704Sob
You can use Webpack & Lazy loading with using angular2-router-loader. See more medium.com/@daviddentoom/…Jeanicejeanie
You're wrong about Webpack! It allows you to combine bundling with lazy loading. Moreover, it transparently bundles deferred modules into chunks.Sniperscope
@AlexKlaus thanks for the example! I was looking for something like that :)Orbicular
An update on Webpack & Lazy loading. Last reincarnation of the package is ng-router-loader. It's included in AngularClass/angular-starter (Angular4 Webpack Starter).Jeanicejeanie
I am brand new to angular, first had a try with quickstart project in which I added some functionalities, everyhting goes well, until you need using some more apis (eg like three.js) . you will find many people problems looking for a reason to knwo why their project does not load the needed api. with similar very poor mistake messages in the console : Error: (SystemJS) XHR error (404 Not Found) loading localhost:3000/three. From my viewpoint it is not professional at all, you will spend hours, days to maybe find the way to solve it . I am definitely switching to webpack .Cupp
"Webpack is entirely different and takes forever to master. It does not do the same thing as SystemJS but, when using Webpack, SystemJS becomes redundant." I gotta disagree. SystemJS still allows dev development without constantly having to build for every change. I can make a change to a TS file, save (which will automatically call tsc.exe and build it), then reload my page and not have any issues. With Webpack, I have to rebuild which can take significantly longer because it will recompile and build everything. I have not been able to find any way to avoid that using Webpack.Inaugural
G
146

If you go to the SystemJS Github page, you will see the description of the tool:

Universal dynamic module loader - loads ES6 modules, AMD, CommonJS and global scripts in the browser and NodeJS.

Because you use modules in TypeScript or ES6, you need a module loader. In the case of SystemJS, the systemjs.config.js allows us to configure the way in which module names are matched with their corresponding files.

This configuration file (and SystemJS) is necessary if you explicitly use it to import the main module of your application:

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

When using TypeScript, and configuring the compiler to the commonjs module, the compiler creates code that is no longer based on SystemJS. In this example, the typescript compiler config file would appear like this:

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

Webpack is a flexible module bundler. This means that it goes further and doesn't only handle modules but also provides a way to package your application (concat files, uglify files, ...). It also provides a dev server with load reload for development.

SystemJS and Webpack are different but with SystemJS, you still have work to do (with Gulp or SystemJS builder for example) to package your Angular2 application for production.

Galenism answered 8/7, 2016 at 9:46 Comment(10)
When you say "with SystemJS, you still have work to do (with Gulp or SystemJS builder for example) to package your Angular2 application for production" is what i currently get with with npm start?Every
In fact, for production, it's not efficient to load a lot of files for modules (Individual files (~300 requests) or Bundled (~40 requests)). You need to gather everything into one or two (your code and third-party library code), compile offline your templates (ngc) and leverage tree shaking to minimize the weight of bundles. This article could interest you: blog.mgechev.com/2016/06/26/…. You also need to uglify CSS files.Galenism
With npm start, you "simply" start a server that will serve your application based on your SystemJS configuration for modules...Galenism
so basically u r saying webpack is better to go with angular 2?Back
Google has officially moved to webpack. So I guess it's better to stick with what majority of the community would be using. I am migrating my systemJS project to webpack soon. Not entirely sure how to do it though.Branchia
@Branchia Do you have a link to this offical announcement?Atomizer
@JonasKello that's the case for angular cli. See this link: github.com/angular/angular-cli in the section "Webpack update"?Galenism
You are saying "When using TypeScript, and configuring the compiler to the commonjs module, the compiler creates code that is no longer based on SystemJS" why its not based on systemjs as systemjs is universal module loader it shouldn't make any difference between node modules or commonjs module to loadMorley
Might be a bit late for my comment, but I would say that WebPack is much more flegged out, even thought it takes much more configuration than systemjs does, it seems more flexible.Pontine
wrote an article about how to migrate from systemjs/jspm to webpack. And explain why jspm + systemjs are so slow in compare with webpack alfilatov.com/posts/…Kelcy
T
1

So far I was using systemjs. It was loading files one by one and first load was taking 3-4 seconds without minified files. After switching to webpack I got a great performance improvement. Now it takes only to load one bundle file (also polyfills and and vendor libs which almost never changed and almost always cached) and that's it. Now it takes just a second to load the client side app. No additional client side logic. As less the number of individual files loaded as higher the performance. When using systemjs you should think about importing modules dynamically to save in performance. With webpack you focus mainly on your logic because performance will be still be good once the bundle is minified and cached in you browser.

Tercel answered 10/7, 2017 at 19:13 Comment(1)
You only answered one of OP's questions, it would have been better to make a comment.Elegit

© 2022 - 2024 — McMap. All rights reserved.