Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can SystemJS plugins modify already transpiled files?

While attempting to get Angular (1.x) working with systemjs I realized that there is not currently the capability (that I know of) to automatically insert $inject into angular components, which keeps the components working even when the arguments to the functions are mangled by the minifier. Manually creating the $inject annotations is tedious, error-prone and violates the DRY principal.

There is a mature npm module called ng-annotate which solves this problem and is used in many similar situations for bundling. As I've been exploring SystemJS, I see that there is a plugin system that includes the ability to translate source code, which is exactly what ng-annotate does.

From what I can see, though, SystemJS only gives you the ability to map a particular file extension to a single loader and all the examples of the plugins are to support a new file type. What I would like to do is post-process the output of SystemJS's transpilation process rather than add a new file type. It seems like SystemJS should be able to do this since it has a processing pipeline, but I can't quite figure out how to hook into it the right way. Right now I am using Browserify to achieve the same effect, but I have ended up with a rather complex set of build tasks and I would like to simplify it with SystemJS if possible.

Other strategies to be able to use ng-annotate in the loader pipeline with SystemJS would be appreciated too.

like image 666
Avi Cherry Avatar asked Sep 10 '15 02:09

Avi Cherry


1 Answers

Eventually I figured out a way, but this feels really clunky. System.src itself uses a hook() function to do this, but it's not exported for use. I'd be grateful for any ways to improve this and I hope eventually a properly supported mechanism for chaining loader functionality becomes available:

var System = require('systemjs');
var systemTranslate = System.translate;
System.translate = function(load) {
  return systemTranslate.call(this, load).then(function (result) {
    if (result) {
      var processedResult = result; // Do your processing here.
      load.source = processedResult;
    }
    return load.source;
  });
}

I haven't experimented much with this, since my particular use cases for System.js building is currently a dead-end (Typescript source-maps are still busted), but presumably you can also return a promise.

I'll leave this answer un-chosen for a while to see if anybody has some better advice.

like image 60
Avi Cherry Avatar answered Oct 21 '22 02:10

Avi Cherry