使用多个baseurls的ES6异步模块

时间:2015-05-31 09:05:09

标签: javascript asynchronous module ecmascript-6 systemjs

ES6模块系统似乎非常适合统一CommonJs / AMD语法。作为requireJs / AMD用户,我想转换为ES6模块(现在使用babel.js)。

但似乎有一个问题;通过阅读文档和教程,似乎无法加载依赖于多个baseurl的模块包。使用requireJs可以使用context字段解决这个问题:

// 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();
  });
});

在main.js

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

在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();
    })
  }
})

在ES6异步模块导入中,这是不可能的,因为System是单例

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 **/ });
});

我的问题是:文档中是否存在我错过的内容(可能将System子类化为能够配置多个baseUrls),或者这是否适用于未来的模块扩展?

2 个答案:

答案 0 :(得分:1)

至少使用当前版本的SystemJS,您可以提供通配符路径。 https://github.com/systemjs/systemjs/wiki/Configuration-Options#paths-unstable

我自己没有使用它,但对于你的情况,似乎你做了

System.baseURL = 'http://path/to/domain/js';
System.paths['plugin-*'] = 'http://path/to/otherdomain/js/plugin-*';

答案 1 :(得分:1)

似乎System.js具有(未记录的)方式 - 通过使用Object.create(System)扩展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();
));

请注意,在browser / nodeJs中实现System对象之前,这种方法可能会中断。但是,希望在ES6中使用class context1 extends System可以实现相同的效果。

实现与requireJs不是100%类似,因为它不可能将当前上下文注入到作用域上下文中的异步加载其他模块(即'要求' - 依赖关系需要替换为m.setSystem(..)或类似的。)