5

I'm deploying a website but I am not able to "bundle" rxjs since I am using the final version of Angular. I can only deploy rxjs by copying the whole folder node_modules/rxjs on my website.

Here is my configuration of SystemJS

    System.config({
        map: {
            'lodash':'http://127.0.0.1/js/lodash.min.js',
            '@angular/core': 'http://127.0.0.1/js/core.umd.min.js',
            '@angular/compiler': 'http://127.0.0.1/js/compiler.umd.min.js',
            '@angular/common': 'http://127.0.0.1/js/common.umd.min.js',
            '@angular/http': 'http://127.0.0.1/js/http.umd.min.js',
            '@angular/platform-browser': 'http://127.0.0.1/js/platform-browser.umd.min.js',
            '@angular/platform-browser-dynamic': 'http://127.0.0.1/js/platform-browser-dynamic.umd.min.js',
            '@angular/router': 'http://127.0.0.1/js/router.umd.min.js',
            '@angular/forms': 'http://127.0.0.1/js/forms.umd.min.js',
            '@angular/upgrade': 'http://127.0.0.1/js/upgrade/bundles/upgrade.umd.js',
            'rxjs':'http://127.0.0.1/js/vendors.bundle.js'
        },
        packages: {
            '/js': {
                defaultExtension: 'js'
            }
        },
        bundles: {
            '/js/app.bundle': ['main']
        }
    });

    document.addEventListener('DOMContentLoaded', function () {
        System.import('main').then(null, console.error.bind(console));
    });

I'm including rxjs in vendors.bundle.js using the following Gulp script :

    gulp.task('vendor.bundle', function() {
        gulp.src([
            'node_modules/systemjs/dist/system-polyfills.js',
            'node_modules/zone.js/dist/zone.min.js',
            'node_modules/reflect-metadata/Reflect.js',
            'node_modules/systemjs/dist/system.src.js',
            'node_modules/rxjs/bundles/Rx.min.js'
        ])
            .pipe(concat('vendors.bundle.js'))
            //.pipe(uglify())
            .pipe(gulp.dest('./dist/js'));
    });

I have errors like the following :

VM9314:3GET http://127.0.0.1/js/vendors.bundle.js/add/operator/map.js 404 (Not Found) ... Error loading http://127.0.0.1/js/vendors.bundle.js/add/operator/map.js as "rxjs/add/operator/map" from http://127.0.0.1/services/global-services/global.services

It's a problem because when we deploy the whole folder, that generate a huge count of request to get all rxjs/*.js files and implies poor performances mainly on mobile devices.

I had not have that perfs problem when I was deploying only the Rx.min.js file.

Can someone tell me how to deploy rxjs using Angular 2.2 et SystemJS ?

3

1 Answer 1

3

Thx to @martin ! :)

Here is the solution: 1. Build your own Rx.min.js using Gulp(in my case) and systemjs-builder

var SystemBuilder = require('systemjs-builder');
gulp.task('rxjs.bundle', function () {
    var builder = new SystemBuilder('./', {
        paths: {"rxjs/*": "node_modules/rxjs/*.js"},
        map: {"rxjs": "node_modules/rxjs"},
        packages: {"rxjs": {main: 'Rx.js', defaultExtension: "js"}}
    });

    builder.bundle('rxjs', 'dist/js/Rx.min.js', {
        sourceMaps: true,
        minify: true,
        mangle: true
    });
});

2.Declare your bundle in your SystemJS configuration file.

System.config({
    map: {
        'lodash':'http://127.0.0.1/js/lodash.min.js',
        '@angular/core': 'http://127.0.0.1/js/core.umd.min.js',
        '@angular/compiler': 'http://127.0.0.1/js/compiler.umd.min.js',
        '@angular/common': 'http://127.0.0.1/js/common.umd.min.js',
        '@angular/http': 'http://127.0.0.1/js/http.umd.min.js',
        '@angular/platform-browser': 'http://127.0.0.1/js/platform-browser.umd.min.js',
        '@angular/platform-browser-dynamic': 'http://127.0.0.1/js/platform-browser-dynamic.umd.min.js',
        '@angular/router': 'http://127.0.0.1/js/router.umd.min.js',
        '@angular/forms': 'http://127.0.0.1/js/forms.umd.min.js',
        '@angular/upgrade': 'http://127.0.0.1/js/upgrade/bundles/upgrade.umd.js'
    },
    packages: {
        '/js': {
            defaultExtension: 'js'
        }
    },
    bundles: {
        '/js/Rx.min.js': [
            "rxjs/*",
            "rxjs/operator/*",
            "rxjs/observable/*",
            "rxjs/add/operator/*",
            "rxjs/add/observable/*",
            "rxjs/util/*"
        ],
        '/js/app.bundle': ['main']
    }
});

document.addEventListener('DOMContentLoaded', function () {
    System.import('main').then(null, console.error.bind(console));
});

Great thx martin, I struggle a lot and the solution was deep inside a very long discussion. I totally missed it :)

Update !

After I have tested that solution, I can confirm that performances are hugely improved !! The duration for loading my home page was about 15s and now just 3s !!

Sign up to request clarification or add additional context in comments.

2 Comments

I don't understand how bundling works with rxjs. I've tried so many times to map all rxjs requests to a single bundle file like you did in your example. SystemJS always requests the bundle/original.js Like so: /js/rxjs.bundle.js/Observable.js If the app is trying to include Observable from rxjs, than according to your "bundles" config, all requests in the array should resolve to Rx.min.js
For information, all that post is useless in my opinion. Now I'm using ahead of time compilation that sprays any compilation process in terms of time and package size. Just as it is simply described here angular.io/guide/aot-compiler. That implies to have 2 projects, one never "compiled" (debug) and another project for AoT (production)