Import a shared service that lives outside the app folder in an angular 2 app in typescript using systemjs
Asked Answered
G

2

6

I have two angular 2 apps in the following structure:

/app
     /app1
     /app2
     /shared

Inside my angular 2 components (written in typescript), I'm importing several modules (that reside in the same folder) without any issues: import { TestService1 } from './test1.service';

However, when I tried to import something from the shared folder, it was unable to load the required module at runtime (browser). import { TestService2 } from '../shared/test2.service'; The browser says: http://something.something.darkside/app/test2.service 404 (Not Found).

I can use the defaultJSExtensions set to true and that will fix the issue. But I would like to know how to configure systemjs correctly to handle this situation.

systemjs.config.js

(function (global) {

    var ngPackageNames = [ bla, ng2packages... ];

    //ng2 apps
    var ngApps = [
        '/app/app1',
        '/app/app2'
    ];

    var map = {
        '@angular': '/node_modules/@angular',
        'rxjs': '/node_modules/rxjs'
    };

    var packages = {
        'rxjs': { defaultExtension: 'js' }
    };

    //adds package entries for each of the needed ng2 packages
    ngPackageNames.forEach(function (pkgName) {
        packages['@angular/' + pkgName] = System.packageWithIndex
            ? { main: 'index.js', defaultExtension: 'js' }
            : { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
    });

    //adds map entries and package entries for the apps
    ngApps.forEach(function (app) {
        var appName = app.substring(app.lastIndexOf('/') + 1);
        map[appName] = app;
        packages[appName] = { main: appName + '.main.js', defaultExtension: 'js' };
    });

    System.config({ map: map, packages: packages });

})(this);
Gunpoint answered 23/7, 2016 at 4:36 Comment(0)
I
4

Include the folder path to your map object.

var map = {
    'shared' : 'app/shared',
    '@angular': '/node_modules/@angular',
    'rxjs': '/node_modules/rxjs'
};

Add in packages add

var packages = {
    'rxjs': { defaultExtension: 'js' },
    'shared': { defaultExtension: 'js' }
};
Inclining answered 23/7, 2016 at 5:45 Comment(3)
Its not a matter of typescript imports thats the problem. Its how SystemJs loads the files and modules. For SystemJs to be able to reference the import, its path must be loaded to SystemJS hence the need to map.Inclining
Just to confirm: we only need the extra systemjs.config.js entry because the file in question sits above the the main entry point for the app, right? eg ../../? systemjs still requests the file from the server though. I'd like to understand how that worls. But I'll mark this as answered as soon you confirm point number one so other people can use this as a reference.Gunpoint
Yes that's right. Ideally if you could have an overall mapping for the folder 'app' it should load the files correctly. However since there are 2 apps would advice against it.Inclining
A
-1
**User "defaultJSExtensions": true in system.config.js**


    (function (global) {
       System.config({
        paths: {
            'npm:': 'node_modules/'
           },
        "defaultJSExtensions": true,
         map: {
Angelangela answered 1/1, 2018 at 16:35 Comment(1)
please add more explanationDerayne

© 2022 - 2024 — McMap. All rights reserved.