These are chat archives for systemjs/systemjs

30th
Dec 2016
Barney Carroll
@barneycarroll
Dec 30 2016 09:16
Hi guys!
I've found SystemJS via rawgit to be a great way of demonstrating full-fat modular ES apps in jsbin without a server
Currently I'm looking to write a wrapper that allows me to relatively tersely import a bunch of modules in one go
I've looked through the API docs, but AFAICT SystemJS API isn't quite low level enough for me to load a bunch of modules in parallel and then execute then in series
amirite?
Barney Carroll
@barneycarroll
Dec 30 2016 09:27
My desired API:
const [ x, y, z ] = gimme( 'path/to/X', 'path/to/Y', 'path/to/Z' )
// where `gimme` is something like
async function gimme( ...uris ){
  // download in parallel (no need to wait for X to finish downloading before requesting Y)
  const files = await Promise.all( uris.map( fetch ) )
  // parse in series (Y cannot execute before X)
  return files.map( file => SystemJS.newModule( file ) )
}
Of course, that :point_up: isn't how SystemJS.newModule works. So my question is, what would I do instead?
Gert Sønderby
@gertsonderby
Dec 30 2016 09:32
Promise.all(uris.map(System.import))
.then(modules => {
    // Run code with modules here
});
Barney Carroll
@barneycarroll
Dec 30 2016 09:33
Yeah, the problem with that is it doesn't respect sequence
Y cannot be allowed to execute before X
Gert Sønderby
@gertsonderby
Dec 30 2016 09:35
Okay, so split it into stages. Import the first batch, then the second batch, etc. But that's a very strange use case IMO, and a fragile one.
Barney Carroll
@barneycarroll
Dec 30 2016 09:36
Is it possible to load the modules in parallel and execute them in series?
BTW, this is how the spec works: systemjs/systemjs#1441
Gert Sønderby
@gertsonderby
Dec 30 2016 09:40
Module dependencies aren't known until execution of the module. And new ones may even crop up later, with System.import calls in conditional code. So module A, which depends on modules 1 and 2, is loaded, then executed, then modules 1 and 2 get loaded and executed. Not really any way around that, apart from header declaration of dependencies of some kind - and even then you'd need to traverse that tree to get the full module list.
Barney Carroll
@barneycarroll
Dec 30 2016 09:41
Well, ES6 modules differ from CommonJS in that you can determine imports and exports statically without parsing the module runtime code
So what happens is module A is scanned for imports, 1 & 2 are found, those are pulled in (recurse as needed), and then when the full dependency graph has been established you execute the code in the necessary sequence
Oh sorry reading #1441 again I realise Guy's saying SystemJS doesn't follow the new spec, so you're right - this wouldn't work anyway because I can't rely on that logic being followed for secondary dependencies
Gert Sønderby
@gertsonderby
Dec 30 2016 09:58
The problem is to do this with CommonJS modules. ES6 modules would be easy enough - all (static) imports at start of file. AMD already declares dependencies separately as well. But CommonJS may have a dependencies anywhere in the code.
Barney Carroll
@barneycarroll
Dec 30 2016 09:58
Right, gotcha
The old methods are incompatible with the new
Node are saying they want to be able to statically identify ES6 modules via an *.mjs extension, specifically to address the problem that you need to know how to parse a file by reference
Do you think that could work for SystemJS?
Brenton Alker
@tekerson
Dec 30 2016 10:53
Is there any hook I can use to normalize bundle deps? They don't seem to pass through normalize or normalizeSync? I can make it work by putting them all in map, but that seems painful when there are a large number.
Brenton Alker
@tekerson
Dec 30 2016 11:03

for example -

  var systemNormalize = System.normalize;
  System.config({
    bundles: {
      '/test/tests/amd-bundle.js': [
        'bundle-1',
        'bundle-2',
      ],
    },
    map: {
      'bundle-1': '/test/tests/bundle-1/bundle-1.js',
    },
    normalize: function(name, parentName, isPlugin) {
      if (name.startsWith('/')) {
        return systemNormalize.call(this, name, parentName, isPlugin);
      }
      return systemNormalize.call(this, `/test/tests/${name}/${name}.js`, parentName, isPlugin);
    },
  });

Given this config - bundle-1 will import from the amd-bundle, but bundle-2 will try and fetch (and fail) even though normalize would give the same result as the map.