Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SystemJS (angular2.0): Loading separate files vs minimize one big JS?

I am a little confused with regards to SystemJS, it seems it automatically loads files separately and doesn't compile and minimize these into one big js file.

I thought the original idea was making requests for different files although smaller is bad practice ? And a prefered large js file (minimified) and produced instead.

This is how I have SystemJS installed right now to load separate files (see below), is this now the recommended way of doing this ?

   System.config({
            packages: {
                app: {
                    format: 'register',
                    defaultExtension: 'js'
                }
            }
        });
        System.import('app/main')
                .then(null, console.error.bind(console));
like image 665
Martin Avatar asked Feb 20 '16 12:02

Martin


1 Answers

System.js (ie the ES6 module standard) changes the development workflow

In Development

Separate files + on-the-fly transpilation are used to make testing, reloading and/or hot-reloading of individual files work without having to transpile/build the entire application bundle after each change.

In Production

The individual files are transpiled and combined into one-or-more bundles using using tools such as Webpack and JSPM.

Both JSPM and Webpack (ie as of version 2) support ES6 modules by default and can leverage tree shaking (ie via rollup.js) to eliminate unused code in the bundle output.

Aside: Eventually, when HTTP2 is supported by most/all servers and the ES6 module standard is natively supported by all browsers, bundling will become an anti-pattern. The benefit of bundling (ie reducing HTTP requests) will no longer be relevant, and the downsides (ie poor caching characteristics, increased development complexity) will be reason enough not to use it.

Tree Shaking

Instead of optimizing bundles by reducing file imports, tree shaking traces all of the application's import paths to determine which code will be included in the output.

For example, if your application uses Rxjs observables to asynchronously fetch data you could import the entire package.

import 'rxjs';

This works well to get started but it's not efficient. The tree shaking step of the bundling process doesn't have a way to determine which code is|isn't used so the entire Rxjs package will be included in the output.

To optimize the output bundle size it would be preferable to import only the features of Rxjs used in your application code.

import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators/map';
import { startWith } from 'rxjs/operators/startWith';

When the tree shaking step runs, it'll include only the code from the Rxjs package required create an Observable and use the map and startWith operators.

Transpilation

In addition to tree shaking and bundling, you'll also need a strategy to transpile the ES6/Typescript source to ES5. Traditionally, automation tools such as Grunt or Gulp were used manually specify the steps required to transpile, concatenate, minify/uglify the code for both development and production.

JSPM can handle all of this by creating a self-executing bundle

jspm bundle-sfx app/main dist/main --uglify

Webpack can accomplish the same

webpack -p app/main.js dist/main.js

In addition to ES6/Typescript transpilation, both tools can also leverage loaders/plugins to support other file types such as css and scss.

like image 175
Evan Plaice Avatar answered Jan 03 '23 15:01

Evan Plaice