【问题标题】:Load CycleJS with SystemJS使用 SystemJS 加载 CycleJS
【发布时间】:2017-03-31 04:28:12
【问题描述】:

我尝试通过 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 => {
    ...
});

但我很快就发现了 cycle-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. 我正在做的是加载循环运行和循环域,然后在循环主页上运行示例。

但我得到了错误:

“TypeError:无法读取未定义的属性‘默认’”

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

谢谢。

【问题讨论】:

    标签: javascript systemjs es6-modules cyclejs


    【解决方案1】:

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

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

    这会打印模块导出。

    我对@9​​87654329@ 没有任何经验,所以我无法判断这是否足够。尽管如此,您可以使用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'] 是否存在。这意味着必须在加载cycle-run.js 脚本之前加载xstream。 SystemJS 的工作方式是加载请求的模块,然后加载其依赖项(您可以在开发人员工具中查看顺序)。所以它与您需要的顺序相反(这与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.*

    【讨论】:

    • 你说得对,我的第一个截图是打错了。最近在节点上工作太多,我又习惯了回调方法。不过,添加元配置似乎并不能解决这个问题。我正在添加一个演示的jsbin。
    猜你喜欢
    • 2016-07-07
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    相关资源
    最近更新 更多