systemjs / plugin-babel

SystemJS Babel Plugin
MIT License
83 stars 33 forks source link

Input source map fexibility #73

Open dmurat opened 7 years ago

dmurat commented 7 years ago

This is proposed patch for issue https://github.com/systemjs/plugin-babel/issues/72

guybedford commented 7 years ago

Can you explain the use case here in a little more detail? The example you use in the issue is of being able to return null - are you using this feature to disable input source maps?

dmurat commented 7 years ago

Oh, I'm sorry. At some point I wanted to describe my use case in more details, but I forgot it.

Here it is. Basically I want to load typescript source maps of Angular 2 to be able to debug Angular 2 itself. In my normal setup I'm using angular's umd modules (es5 code) as recommended by google. Unfortunately, they do not distribute corresponding source maps for these umd modules, and this is known issue.

However, angular also distributes es6 code, together with corresponding TypeScript source maps. To be able to load es6 I need transpiler, and this is where babel and plugin-babel enter the picture.

As I can see, plugin-babel automatically kicks in as soon as es6 code id detected during loading. In my case this means that angular's source is currently loading (since I do not have any other es6 code in dependencies). Therefore, for angular I want to supply the source map for a module that is just being loaded. This means that I need somehow provide inputSourceMap object to the babel. Based on systemjs' load object I can find out the address of file being loaded and load corresponding source map via http:

  meta: {
    '*.js': {
      babelOptions: {
        sourceMaps: true,
        inputSourceMapFunction: function(load) {
          var request = new XMLHttpRequest();
          request.open('GET', load.address + '.map', false);  // `false` makes the request synchronous
          request.send(null);

          if (request.status === 200) {
            return JSON.parse(request.responseText);
          }
          else {
            return null;
          }
        }
      }
    }
  }

I'm aware that solution is not pretty and not performant, but this is the ONLY way that I was able to find to see the actual angular's typescript code while debugging. So, I guess, it is really important to me :-), but maybe might be useful to somebody else.

guybedford commented 7 years ago

@dmurat right thanks for clarifying, yes unfortunately this does sound a little too specific of a use case to implement as a feature, as it is out of the core use case for this plugin.

dmurat commented 7 years ago

In the context of the plugin, I really just want to be able to provide inputSourceMap based on file being loaded. In my opinion, actually babel should do this based on source map comment's present in the code. My solution is just a simple alternative which should not harm anybody. Just a simple callback which returns some object. Nothing more...

guybedford commented 7 years ago

@dmurat picking up source map comments from the source code would be a better approach. If you're interested in working on a PR to support that then I'll gladly accept it.

dmurat commented 7 years ago

I agree, and this can be implemented right from that callback I'm begging for. But I need a callback first... :-) However, I guess you had something else in the mind :-) Can you, please, elaborate a bit, how this should be implemented at the conceptual level.

guybedford commented 7 years ago

@dmurat it can be implemented with a regular expression on the source to check the sourceMappingURL comment and then a custom fetch to retrieve that and pass it into Babel.

dmurat commented 7 years ago

If I understood correctly, you will like to add full support for input source maps in place of current passing of load.metadata.sourceMap in plugin-babel.js?

If so, I can try to do this. To start, I can use one clarification. How should I approach loading non-inlined source maps? Is it valid to wrap http request in a Promise that can be appended to Promise.all which handles loading of babel plugins and presets? Or is there a better way?