angularsystemjssystemjs-builderng-packagr

How to handle the increasing size of bundled file using systemjs builder


We are in the process of upgrading our huge angularjs application to a hybrid angular application (angularjs + angular5) using systemjs. We have started implementing new features in angular 5. I am using systemjs-builder to create a bundled file of my main.ts and include this file using script tag in index.html.

Now, the problem is systemjs-builder is packaging the entire content of main.ts along with all of its dependencies into a single file(including app.module.ts, routes, services, components) everything that is referred from main.ts.

After minification my file size is 1.2MB which is very huge. My performance right now is fine. But, in future as we keep adding more components or services, the file size of the bundled file increases and it might result in slowness on client side. How do I get rid of this problem.

system_prod.config file

    System.config({
transpiler: 'ts',
typescriptOptions: {
    // Copy of compiler options in standard tsconfig.json
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true
},
meta: {
    'typescript': {
        "exports": "ts"
    },
    '*.json': { "loader": "json" }

},
paths: {
    // paths serve as alias

    'npm:': 'node_modules/'



},
// map tells the System loader where to look for things
map: {
    // our app is within the app folder
    'app': 'js',

    // angular bundles
    '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
    '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
    '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
    '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
    '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
    '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
    '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
    '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
    '@angular/upgrade': 'npm:@angular/upgrade/bundles/upgrade.umd.js',
    '@angular/upgrade/static': 'npm:@angular/upgrade/bundles/upgrade-static.umd.js',
    '@angular/common/http': 'npm:@angular/common/bundles/common-http.umd.js',
    'tslib': 'npm:tslib/tslib.js',

    // other libraries
    'rxjs':                      'npm:rxjs',
    'ngx-cookie-service':        'npm:ngx-cookie-service/cookie-service/cookie.service.js',
    'ts':                        'npm:plugin-typescript/lib',
    'typescript':                'npm:typescript/lib/typescript.js',
    'angularscholarshipseed':     'npm:angular-scholarship-seed.umd.js'/*This is the umd file that is generated from a different web war and published as a npm dependency */
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
    app: {
        main: './main.ts',
        defaultExtension: 'ts'
    },
    rxjs: {
        defaultExtension: 'js'
    },
    ts: {
        main: './plugin.js',
        defaultExtension: 'js'
    }

}

})

Code in gruntfile.js -- To generate the bundled file

            systemjs: {
        options: {
            sfx: true, //this one is required to not have dependance on SystemJs
            baseURL: "<%= basedir %>",
            configFile: '<%= basedir %>/system_prod.config.js',
            minify: false, //to avoid naming issues
            build: {
                mangle: false
            }
        },main_dist:{
            files: [{"src": "<%= basedir %>/main.ts","dest": "<%= basedir %>/js/system-generated.min.js"}]
        }
    }

I have included the system-generated.min.js file using script tag in index.html.

Any help is greatly appreciated. I am really worried that in near future as application grows, the bundled file size also grows right? This might result in slowness on client side while downloading that huge bundled file.

Note: We didn't find good documents using angular-cli or webpack for a hybrid angular application. Mostly everywhere they spoke about using systemjs only. That is the reason we have started the upgrade process using systemjs.


Solution

  • Systemjs-builder uses rollup, and rollup now support code-splitting (see there and there). I don't know, how exactly use code-splitting from systemjs-builder, but support of code-splitting in rollup was made by author of systemjs and jspm (this pr). So, I think it should be supported.

    Using code-splitting you can split your large bundle to pieces, and load them only on demand.