SystemJs Ignores Angular Dependency Bundle
Asked Answered
C

1

-1

I am trying to get my angular application to the point where it is ready for distribution and I have managed to create 2 bundles, one for my angular application and one for my dependencies (which include the angular framework and the rxjs framework). I am using systemjs builder to do the bundling and using gulp to run the builder. Both bundles are produced and my custom bundle (which contains my code) is loaded by the front end but the vendor/dependency bundle is ignored and the dependencies are still loaded from the node_modules folder.

I'm thinking that it is an issue with my dist-system-config.js file that I use in the final distribution.

My solution is based mostly on this previous answer with a couple of exceptions like not including/inlining my html templates and adding node_modules to the exclusion path of the dependencies.

I will include everything I believe is relevant to the problem, if more is needed please let me know.

Just to reiterate, the application loads and runs OK but instead of loading the dependencies from dependencies.bundle.js they are loaded from the original location(s) in the node_modules folder. The app.bundle.js is loaded without any issues.


Index.html

<script src="/node_modules/core-js/client/shim.min.js"></script>
<script src="/node_modules/zone.js/dist/zone.min.js"></script>
<script src="/node_modules/reflect-metadata/Reflect.js"></script>
<script src="/node_modules/systemjs/dist/system.js"></script>

<script src="/bundles/dependencies.bundle.js"></script>
<script src="/bundles/app.bundle.js"></script>
<script src="/Scripts/dist-system-config.js"></script>

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

app/boot.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);

Scripts/dist-system-config.js

System.config({
    baseURL: '/',
    paths: {
        'npm:': 'node_modules/'
    },
    map: {
        'app': 'dist/app',

        // angular bundles
        '@angular/core': 'npm:@angular/core/bundles/core.umd.min.js',
        '@angular/common': 'npm:@angular/common/bundles/common.umd.min.js',
        '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.min.js',
        '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.min.js',
        '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
        '@angular/http': 'npm:@angular/http/bundles/http.umd.min.js',
        '@angular/router': 'npm:@angular/router/bundles/router.umd.min.js',
        '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.min.js',
        'rxjs': 'npm:rxjs'
    },
    packages: {
        'app': { main: './boot.js', defaultExtension: 'js' },
        'rxjs': { defaultExtension: 'js' }
    }
});

gulpfile.js

var gulp = require('gulp'),
    tsc = require('gulp-typescript'),
    Builder = require('systemjs-builder');

gulp.task('bundle', ['bundle-app', 'bundle-dependencies'], function(){});

gulp.task('app-components', function () {
    return gulp.src('Scripts/app/**/*.ts')
        .pipe(tsc({
            "target": 'es5',
            "module": 'commonjs',
            "moduleResolution": 'node',
            "lib": [ 'es2015', 'dom', 'es2015.iterable' ],
            "sourceMap": true,
            "emitDecoratorMetadata": true,
            "experimentalDecorators": true,
            "removeComments": true,
            "noImplicitAny": false
        }))
        .pipe(gulp.dest('dist/app'));
});

gulp.task('bundle-app', ['app-components'], function() {
    // optional constructor options
    // sets the baseURL and loads the configuration file
    var builder = new Builder('', 'Scripts/dist-system-config.js');

    return builder
        .bundle('dist/app/**/* - [node_modules/@angular/**/*.js] - [node_modules/rxjs/**/*.js]', 'bundles/app.bundle.js', { minify: true})
        .then(function() {
            console.log('Build complete');
        })
        .catch(function(err) {
            console.log('Build error');
            console.log(err);
        });
});

gulp.task('bundle-dependencies', ['app-components'], function() {
    // optional constructor options
    // sets the baseURL and loads the configuration file
    var builder = new Builder('', 'Scripts/dist-system-config.js');

    return builder
        .bundle('dist/app/**/*.js - [dist/app/**/*.js]', 'bundles/dependencies.bundle.js', { minify: true})
        .then(function() {
            console.log('Build complete');
        })
        .catch(function(err) {
            console.log('Build error');
            console.log(err);
        });
});

package.json (Relevant versions only)

"@angular/***": "4.2.6",
"canonical-path": "0.0.2",
"gulp": "3.9.1",
"gulp-typescript": "^3.2.0",
"rimraf": "2.6.1",
"rxjs": "5.4.2",
"systemjs": "0.20.14",
"systemjs-builder": "0.16.9",
"typescript": "2.4.1",
Carnal answered 11/7, 2017 at 19:39 Comment(7)
'app': { main: './main.js', defaultExtension: 'js' } in my configuration is { main: 'app/boot.js', defaultExtension: 'js' } so if your boot file is named main.js instead of boot.js then it should be { main: 'app/main.js', defaultExtension: 'js' },. And no need for 'main': 'dist/app/main.js', (I guess)Wanonah
@AnkitSingh - thank you, I updated the Scripts/dist-system-config.js based on your comment but am still encountering the same behavior.Carnal
@AnkitSingh - would referencing the umd bundles from angular have anything to do with it? (instead of another .js file)Carnal
@AnkitSingh - see the answer below by Louis, the load/script tag order matters. Thank you again for your help and previous answer on the other thread (I did up-vote it).Carnal
Oh I see (I was shooting in the air, hvn't used SystemJS for months now) ... You're welcome. .... Well, what can I say, Thank you very much! :)Wanonah
@AnkitSingh - By the way, is the reason you have not used it in a while because you are using something else for bundling? If so might I ask what are you using now?Carnal
sure, Angular CLI, it just works without much hassle. See the accepted answer above my answer on that Other question for more info. or you can use This Starter from @AngularClassWanonah
H
2

Configure SystemJS before you load any bundle.

I was able to reproduce your problem. What I found is that if the bundles are loaded before SystemJS is configured, then SystemJS ignores the bundles that have been loaded. If load the bundles after configuring SystemJS then everything is fine. So you should have your scripts in this order:

<script src="/Scripts/dist-system-config.js"></script>
<script src="/bundles/dependencies.bundle.js"></script>
<script src="/bundles/app.bundle.js"></script>

Here's a comment by SystemJS' author (Guy Bedford) explaining why:

You need to configure SystemJS first before loading bundles because bundles run through normalization, and hence need configuration present in order to normalize correctly.

Hama answered 12/7, 2017 at 11:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.