Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ES6 async modules using multiple baseurls

The ES6 module system seems to be a proper fit for unifying the CommonJs / AMD syntaxes. As a requireJs/AMD-user I'd like to convert to ES6 modules (using babel.js for now).

There seems to be one problem though; reading through the docs and tutorials, there doesn't seem to be possible to load module packages that are dependendent on more than one baseurl. Using requireJs this is solvable using the context field:

// async dependencies are loaded from http://path/to/domain
var contextedRequire1 = require.config({
  baseUrl: 'http://path/to/domain/js',
  context: 'mainContext'
});    

// async dependencies are located on http://path/to/otherdomain
var contextRequire2 = require.config({
  baseUrl: 'http://path/to/otherdomain/js',
  context: 'pluginContext'
});

contextedRequire1(['main.js'], function(main){
  // loaded using http://path/to/domain/js/main.js
  contextedRequire2(['plugin-lazyloading-deps.js'], function(plugin){
    plugin.init();
  });
});

In main.js

define(['main-deps'], function(mainDeps){
  // loaded using http://path/to/domain/js/main-deps.js
})

In plugin-lazyloading-deps.js

define(['require'], function(require){
  // loaded using http://path/to/otherdomain/js/plugin-lazyloading-deps.js
  if(Modernizr.touch) {
    require(['hammer'], function(){
      // loaded using http://path/to/otherdomain/js/hammer.js
      hammer.init();
    })
  }
})

In ES6 async module imports this isn't possible, since System is a singleton

System.baseURL = "http://path/to/domain/js";
System.import("main").then(function(main){
  // loaded using http://path/to/domain/js/main.js

  // This will potentially break when main.js tries to load hammer.js from http://path/to/domain/js
  System.baseURL = "http://path/to/otherdomain/js";
  System.import("plugin-lazyloading-deps").then(function(){ /** code **/ });
});

My question is: Is there something in the docs that I've missed (possible to subclass System to be able to config several baseUrls), or is this something in the works for future module extensions?

like image 201
Aksel N. Avatar asked Jun 17 '26 08:06

Aksel N.


2 Answers

At least with the current version of SystemJS, you can provide wildcard paths. https://github.com/systemjs/systemjs/wiki/Configuration-Options#paths-unstable

I haven't used it myself, but for your case, seems you'd do

System.baseURL = 'http://path/to/domain/js';
System.paths['plugin-*'] = 'http://path/to/otherdomain/js/plugin-*';
like image 82
loganfsmyth Avatar answered Jun 19 '26 22:06

loganfsmyth


It seems as if System.js has an (undocumented) way - by extending the System object using Object.create(System).

var context1 = Object.create(System);
context1.baseURL = 'http://path/to/otherdomain/js';
context1.import('plugin-lazyloading-deps').then(function(m){
  m.setSystem(context1);
  m.initialize();
));

Please note that until the System object is implemented in browsers/nodeJs, this approach may break. Hopefully though, the same effect may be achievable using class context1 extends System in ES6.

The implementation is not 100% analogous to requireJs, since it's not possible to inject the current context to async-load other modules from within a scoped context (ie. the 'require'-dependency needs to be replaced with m.setSystem(..)or similar).

like image 20
Aksel N. Avatar answered Jun 19 '26 22:06

Aksel N.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!