【问题标题】:Angular2 2.0.x and Rx 5 beta.12 bundleAngular2 2.0.x 和 Rx 5 beta.12 捆绑包
【发布时间】:2016-10-12 06:34:50
【问题描述】:

我目前正在更新使用 Angular2 npm 包和 RxJs 的项目的依赖项。我正在更新到 Angular 的 2.0.2 稳定版本,它取决于 Rx5 beta.12。 对于我的 Web 应用程序,我只部署 Rx.min.js 包并在我的 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 包导入。

在不部署 node_module 本身的情况下导入 Rx.js bundle 时,Angular2 2.0.x 的最新技术是什么。我需要捆绑版本!我使用的是 Rx.js 包的 umd 版本,之前它似乎不存在了。

【问题讨论】:

  • 如果我在你的鞋子里,我会为你的应用程序使用 angular-cli。它将捆绑您的应用程序,您可以花时间制作应用程序而不是修复库导入问题。

标签: angular rxjs systemjs rxjs5


【解决方案1】:

我使用 Angular2rxjs@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'
},

然后我从map 列表中删除了rxjs。现在它会加载一个 Rx.js 文件。

【讨论】:

  • 我已经看到了这项工作,并且 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】:

这对我有用,一旦我开始使用Angular2 的其他位,例如routing,通过rxjs* 加载就会导致问题。

这个问题详细讨论here,解决方法是使用自己的loader比如(code credit nros

显然,它将在未来的版本中修复,我怀疑这会因为 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 && !(/^\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"
                }
            }
        }
    }
});

【讨论】:

    猜你喜欢
    • 2016-07-16
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多