使用 SystemJS 加载 CycleJS

Load CycleJS with SystemJS

我尝试通过 SystemJS 从他们的 CDN 加载 Cycle DOM,例如:

System.config({
  map: {
    'cycle-dom': 'https://unpkg.com/@cycle/dom@17.1.0/dist/cycle-dom.js',
    'xstream': 'https://cdnjs.cloudflare.com/ajax/libs/xstream/10.3.0/xstream.min.js',
  }
});

System.import('cycle-dom', cycleDOM => {
    ...
});

但我很快发现周期-dom 需要xstream。所以我尝试同时加载:

Promise.all([
  System.import('xstream'),
  System.import('cycle-dom')
])
.then(([xs, cycleDOM]) => {
  ...
});

但我仍然得到同样的错误。看起来 cycle-dom 在首次加载时期望 xstream 存在于 window 上。所以我尝试了:

System.import('xstream')
  .then(xs => window['xstream'] = xs)
  .then(() => System.import('cycle-dom'))
  .then(cycleDOM => {
    ...
  });

我觉得我的做法全错了。我怎样才能做到这一点?

更新:

按照下面马丁的建议,我尝试将 xstream 配置为 cycle-dom 的依赖项。

Here's a jsbin that demonstrates. 我正在做的是加载 cycle-运行 和 cycle-dom,然后 运行 将示例从 cycle 主页上删除。

但我收到错误消息:

"TypeError: Cannot read property 'default' of undefined"

Undefined 在这种情况下是 cycle-dom 尝试加载 window['xstream'],它没有被加载。

谢谢。

System.import() 调用 returns 一个 Promise,因此您需要将回调放入其 then() 方法中(第二个参数是 the parent name;不是回调)。

System.import('cycle-dom').then(function(cycleDOM) {
  console.log(cycleDOM);
});

这将打印模块导出。

我没有任何使用 cycle.js 的经验,所以我不知道这是否足够。尽管如此,您可以使用 meta config:

设置此包依赖项
System.config({
  map: {
    'cycle-dom': 'https://unpkg.com/@cycle/dom@17.1.0/dist/cycle-dom.js',
    'xstream': 'https://cdnjs.cloudflare.com/ajax/libs/xstream/10.3.0/xstream.min.js',
  },
  meta: {
    'cycle-dom': {
      deps: [
        'xstream'
      ]
    }
  }
});

同样,我不知道这是否足够。 SystemJS 文档包含很好解释的示例,说明如何加载需要注册一些全局变量的依赖项。参见 https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#shim-dependencies

编辑:
在这种情况下,它有点复杂。 cycle-run.js 脚本可能是由 browserify 生成的,您可以看到它包含如下一行:

var xstream_1 = (typeof window !== "undefined" ? window['xstream'] : typeof global !== "undefined" ? global['xstream'] : null);

这会在加载时检查 window['xstream'] 是否存在。这意味着 xstream 必须在加载 cycle-run.js 脚本之前加载。 SystemJS 的工作方式是加载请求的模块,然后加载其依赖项(您可以在 Developer Tools 中查看顺序)。所以它的顺序与您需要的顺序相反(这与 my question on SystemJS GitHub page 非常相似)。

这意味着您需要重组导入调用:

System.config({
  // ...
  meta: {
    'xstream': {
      format: 'global',
      exports: 'xstream',
    }
  }
});

System.import('xstream').then(function() {
  Promise.all([
    System.import('cycle-run'),
    System.import('cycle-dom'),
  ])
  .then(([cycle, cycleDOM]) => {
    // ...
  });
});

这会在加载 cycle-run 之前注册 xstream。此外,xstreammeta 配置确保 window.xstream 仅存在于这些回调中,不会泄漏到全局范围。

查看更新后的演示:https://jsbin.com/qadezus/35/edit?js,output

还要使用 formatexports,您需要使用较新的 SystemJS 0.20.* 而不是 0.19.*