Пакет Angular2 2.0.x и Rx 5 beta.12

#angular #rxjs #systemjs #rxjs5

#angular #rxjs #systemjs #rxjs5

Вопрос:

В настоящее время я обновляю зависимости моего проекта, в котором используются пакеты Angular2 npm и, следовательно, RxJS. Я обновляю до стабильной версии 2.0.2 angular, которая зависит от Rx5 beta.12. Для моего веб-приложения я развертываю только Rx.min.js свяжите и загрузите его с тегом script в моем index.html досье. Этот подход отлично работал раньше с пакетом Rx umd, но в то же время вызывает ошибки, поскольку мне кажется, что разработчики RxJS удалили разные версии пакета ради одного общего файла пакета. т.е. Rx.js вместо того , чтобы Rx.umd.js и так далее.

Я использую загрузчик модуля SystemJS, и если я не буду выполнять никаких дополнительных шагов, эти ошибки будут возникать с любым символом платформы RxJS:

 GET http://localhost:8080/rxjs/Subject.js 404 (Not Found)
  

Я понял, что Rx теперь определен глобально (window.Rx) и содержит все необходимые материалы. Итак, я попытался определить эти символы в SystemJS вручную, выполнив что-то вроде этого:

 function defineGlobalModule( parentModuleName, simpleName, moduleValue ) {
  var fqModuleName = parentModuleName   simpleName;
  System.amdDefine( fqModuleName, ["require", "exports"], function (require, exports) {
       "use strict";
       exports[ simpleName ] = moduleValue;
  }); 

  if( typeof moduleValue === "object" )
     for( var key in moduleValue )
       defineGlobalModule( fqModuleName   "/", key, moduleValue[ key ] )
}

defineGlobalModule( "", "rxjs", global.Rx );
  

Это заставило импорт стиля ‘rxjs / Subject’ снова работать. Но теперь я получаю много подобных ошибок:

 GET http://localhost:8080/rxjs/operator/toPromise.js 404 (Not Found)
GET http://localhost:8080/rxjs/observable/fromPromise.js 404 (Not Found)
  

Эти файлы импортируются с помощью angular forms.umd.js например, связка.

Каково современное состояние Angular2 2.0.x, когда дело доходит до импорта Rx.js связывайте без развертывания самого node_module. Мне нужна комплектная версия! Я использовал umd-версию Rx.js пакет, перед которым, кажется, больше не существует.

Комментарии:

1. если бы я был на вашем месте, я бы использовал angular-cli для вашего приложения. Это объединит ваше приложение, и вы сможете потратить время на создание своего приложения вместо устранения проблем с импортом библиотеки.

Ответ №1:

Возможно, я сделал именно то, что вы ищете, Angular2 и rxjs@5.0.0-beta.12 который теперь распространяется как globals , и umd пакет, вероятно, больше не поддерживается (как вы и сказали):

Смотрите живую демонстрацию: https://plnkr.co/edit/z4gg2XBoQDgYXev0Csuq

В принципе, я только что обновил свою конфигурацию SystemJS:

 paths: {
  'rxjs*': 'https://unpkg.com/@reactivex/rxjs@5.0.0-beta.12/dist/global/Rx.js'
},
  

Затем я удалил rxjs из map списка. Теперь он загружает один Rx.js файл.

Комментарии:

1. Я видел эту работу, и plunk работает очень хорошо, но как только вы начинаете использовать больше бит Angular, он останавливается.. Я получаю следующую ошибку core.umd.js:3010 TypeError: Cannot read property 'call' of undefined at RouterPreloader.setUpPreloading (http://localhost:5000/node_modules/@angular/router/bundles/router.umd.js:3542:58) Я использовал пользовательский загрузчик, который я нашел в следующей проблеме git github.com/angular/angular/issues/9359

Ответ №2:

Это сработало для меня, загрузка через rxjs* вызвала проблему, как только я начал использовать другие биты Angular2 , такие как routing .

Эта проблема подробно обсуждается здесь, и решение заключается в использовании вашего собственного загрузчика, такого как (code credit nro)

По-видимому, это будет исправлено в будущей версии, я подозреваю, что это сдерживается, поскольку rxjs все еще находится в бета-версии.

rxjsLoader.js

 // see: https://github.com/angular/angular/issues/9359
// in case all parts of RxJS are loaded with a single file (eg: Rx.js), Angular 2 may have
// difficulties using/requiring the various parts.
// this custom loader translates requests to these parts to the already loaded Rx entity.
//
// eg: Angular:
//      require('rxjs/observable/from')  -->  Rx.Observable
//      require('rxjs/operator/concatMap')  -->  Rx.Observable.prototype
//      require('rxjs/util/EmptyError')  -->  Rx
//
// Angular will access 'rxjs/observable/from' as rxjs_observable_from.from
// so, the last part of the included module (eg: 'from') denotes the property name to access
// the required value.
SystemJS.amdDefine(SystemJS.baseURL   "rxjsLoader.js", ["rxjs"], function (Rx) {
    'use strict';

    // custom loader for RX.js to instantiate the correct value
    // see: https://github.com/ModuleLoader/es-module-loader/blob/v0.17.0/docs/loader-extensions.md
    return {
        fetch: function fetch(loadData) {
            return ""; // no fetch - "Rx" is already loaded!
        },

        translate: function translate(loadData) {
            return "";
        },

        instantiate: function instantiate(loadData) {

            // loadData.name contains the full URL
            var propertyName = loadData.name.replace(/^.*/rxjs-parts/(.*)$/i, "$1").replace(/.js$/i, "");

            // if property name is not empty, evaluate and use it
            if (propertyName.length > 0 amp;amp; !(/^s*$/.test(propertyName))) {
                var parts = propertyName.split("/"),
                    targetObject = Rx
                ;

                // Angular 2 expects the return value to be an object
                // and the last part of the name to be the property of that object

                for (var i=0; i < parts.length-1; i  ) {
                     var partName = parts[i],
                         upperCaseName = partName.charAt(0).toUpperCase()   partName.slice(1)
                     ;

                     // handle special case for "operator/*"
                     if (partName === "operator") {
                         return Rx.Observable.prototype;

                     } else if (targetObject[partName] !== undefined) {
                         targetObject = targetObject[partName];

                     } else if (targetObject[upperCaseName] !== undefined) {
                         targetObject = targetObject[upperCaseName];

                     } else {
                         // skip name and try with next part name. eg: "utils"
                         continue;
                     }
                }

                return targetObject;

            } else {
                // return the Rx as default
                return Rx;
            }
        }
    };
});
  

systemjs-config-using-custom-rx-loader.js

 SystemJS.config({

    baseURL: '/',

    map: {
        "rxjs": "Rx.js"
    },
    paths: {
        "Rx.js/*": "rxjs-parts/*"
    },
    packages: {
       "rxjs-parts": {
            meta: {
                "*": {
                    loader: "rxjsLoader.js"
                }
            }
        }
    }
});