【问题标题】:ES6 async modules using multiple baseurls使用多个 baseurl 的 ES6 异步模块
【发布时间】:2015-05-31 09:05:08
【问题描述】:

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),或者这是否正在为未来的模块扩展工作?

【问题讨论】:

  • 从不同域加载异步模块包的用例是多个团队在一个大型站点(主应用程序)中创建子应用程序 - 需要在不同域上构建和部署正在重新部署的主应用程序。

标签: javascript asynchronous module ecmascript-6 systemjs


【解决方案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-*';

【讨论】:

  • 谢谢,不是我想要的,但很高兴看到路径通配符比 requireJs 中的功能更好。
【解决方案2】:

似乎 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();
));

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

该实现并非 100% 类似于 requireJs,因为无法注入当前上下文以从作用域上下文中异步加载其他模块(即,需要将“require”依赖项替换为 m.setSystem(..)或类似的)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 2016-11-15
    • 1970-01-01
    相关资源
    最近更新 更多