Search code examples
javascriptangulartypescriptrequiresystemjs

Load JavaScript file in angular2 app


I'm working on a angular2 application written in TypeScript.

This works:

I have a module called plugin-map.ts which looks something like this:

import { Type } from '@angular/core';

import { SomeComponent } from './plugins/some.component';

export const PluginMap: { [key: string]: Type<any> } = {
    'e690bec6-f8d1-46a5-abc4-ed784e4f0058': SomeComponent
};

It gets transpiled to a plugin-map.js which looks something like this:

"use strict";
var some_component_1 = require('./plugins/some.component');
exports.PluginMap = {
    'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
//# sourceMappingURL=plugin-map.js.map

And in other modules I'm importing my PluginMap like this:

import { PluginMap } from './plugin-map';

What I want:

Now I want to create plugin-map.js at runtime when my server starts. So I want to get rid of my plugin-map.ts and instead have only a (generated) plugin-map.js. And I don't want to have any transpile-time dependencies to that plugin-map.js.

What I tried:

In modules where I need to access the PluginMap I replaced the import statement with a declaration like this:

declare const PluginMap: { [key: string]: Type<any> }; 

Now of course at runtime I get a Error: (SystemJS) 'PluginMap' is undefined. So my next step was to load plugin-map.js explicitly from my index.html like this:

...
<script src="js/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
      System.import('./app/plugins/plugin-map.js').catch(function (err) { console.error(err); });
      System.import('app').catch(function(err){ console.error(err); });
</script>
...

When I start my application I can see that the browser actually requests the plugin-map.js file. But I still get the Error: (SystemJS) 'PluginMap' is undefined.

Question:

How/where do I have to load my generated plugin-map.js so that this works?


Solution

  • I had to make sure that PluginMap is available in the global context. So the generated plugin-map.js has to look like this:

    var some_component_1 = require('./plugins/some.component');
    PluginMap = {
        'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
    };
    

    and not like this:

    "use strict";
    var some_component_1 = require('./plugins/some.component');
    exports.PluginMap = {
        'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
    };
    //# sourceMappingURL=plugin-map.js.map
    

    Now it seems to work.