Загрузить CycleJS с помощью SystemJS

Я попытался загрузить Cycle DOM из их CDN через SystemJS примерно так:

System.config({
  map: {
    'cycle-dom': 'https://unpkg.com/@cycle/[email protected]/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.

Вот демонстрация jsbin. Я загружаю цикл-выполнение и cycle-dom, а затем запустить пример с домашней страницы цикла.

Но я получаю сообщение об ошибке:

"TypeError: Не удается прочитать свойство "по умолчанию" неопределенного"

Undefined в данном случае означает, что cycle-dom пытается загрузить window['xstream'], который не загружается.

Спасибо.


person nicholas    schedule 31.03.2017    source источник


Ответы (1)


Вызов System.import() возвращает обещание, поэтому вам нужно поместить обратный вызов в его метод then() (второй параметр — имя родителя; не обратный вызов).

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

Это печатает экспорт модуля.

У меня нет опыта работы с cycle.js, поэтому я не могу сказать, достаточно это или нет. Тем не менее, вы можете установить зависимости этого пакета с помощью meta config:

System.config({
  map: {
    'cycle-dom': 'https://unpkg.com/@cycle/[email protected]/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 заключается в том, что он загружает запрошенный модуль, а затем загружает его зависимости (вы можете увидеть порядок в инструментах разработчика). Таким образом, это порядок, противоположный тому, который вам нужен (это очень похоже на мой вопрос на странице SystemJS GitHub).

Это означает, что вам нужно реструктурировать вызовы импорта:

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]) => {
    // ...
  });
});

Это регистрирует xstream перед загрузкой cycle-run. Также с конфигурацией meta для xstream это гарантирует, что window.xstream существует только внутри этих обратных вызовов и не просачивается в глобальную область.

Посмотрите обновленную демонстрацию: https://jsbin.com/qadezus/35/edit?js,output

Также для использования format и exports вам нужно использовать более новый SystemJS 0.20.*, а не 0.19.*.

person martin    schedule 31.03.2017
comment
Вы абсолютно правы, мой первый фрагмент был напечатан неправильно. Слишком много работы в узле в последнее время, я снова привык к обратному вызову. Однако добавление метаконфигураций, похоже, не решает эту проблему. Я добавляю jsbin, который демонстрирует. - person nicholas; 01.04.2017