#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"
}
}
}
}
});