简体   繁体   English

如何从'Rx`导入`Observable`(非角度)

[英]How to import `Observable` from `Rx` (not angular)

I'm using SystemJS to load my es2015 project into the browser. 我正在使用SystemJS将我的es2015项目加载到浏览器中。

This is what I did 这就是我做的

import {Observable} from 'rxjs/Rx';

const button = document.querySelector('button');
const start$ = Observable.fromEvent(button, 'click');

In this case Observable is undefined . 在这种情况下, Observableundefined So I tried 所以我试过了

import Observable from 'rxjs/Observable';

In which case Observable is an object but Observable.fromEvent is undefined (it seems to be an empty object) 在这种情况下, Observable是一个对象,但Observable.fromEventundefined (它似乎是一个空对象)

Finally I did 最后我做到了

import Rx from 'rxjs/Rx' // Rx.Observable

which did work. 哪个做了。 Any ideas why the other two didn't work? 任何想法为什么其他两个不起作用? I have seen code in which they used these. 我见过他们使用过的代码。 What would be the preferred way to import Observable ? 导入Observable的首选方法是什么?

UPDATE: As stated below its all described in the README . 更新:如下所述,它在README中描述。 However if I do that 但是,如果我这样做

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';

const start$ = Observable.fromEvent(startButton, 'click');

I get Observable is undefined . 我得到Observableundefined And if I do 如果我这样做

import Observable from 'rxjs/Observable';

the Observable is an empty object again. Observable是一个空对象。 The fromEvent is not added. 未添加fromEvent

I'm using RxJs 5.1.1 and here is my index.html/systemjs part: 我正在使用RxJs 5.1.1,这是我的index.html / systemjs部分:

 <script src="./node_modules/systemjs/dist/system.js"></script>
  <script>
      SystemJS.config({
          baseURL: 'node_modules',
          packages: {
              '.': {
                  defaultJSExtensions: 'js'
              }
          },
          map: {
              'plugin-babel': 'systemjs-plugin-babel/plugin-babel.js',
              'systemjs-babel-build': 'systemjs-plugin-babel/systemjs-babel-browser.js'
          },
          transpiler: 'plugin-babel'
      });

      SystemJS.import('/js/main.js');
  </script>

As it notes in the README , you can use import { Observable } from 'rxjs/Observable'; 正如它在README中所说,你可以使用import { Observable } from 'rxjs/Observable'; :

To import only what you need by patching (this is useful for size-sensitive bundling) 仅通过修补导入所需内容(这对于大小敏感的捆绑非常有用)

This gives you a very minimal Observable , to which you need to explicitly add any extra functionality you plan to use; 这为您提供了一个非常小的Observable ,您需要明确添加您计划使用的任何额外功能; in your case, follow it with: 在您的情况下,请遵循:

import 'rxjs/add/observable/fromEvent';

I was having exactly the same issue when transpiling from TypeScript. 从TypeScript转换时,我遇到了完全相同的问题。 Then I switched to using just the compiled scripts with exactly the same options and it worked so I'm suspicious it has something to do with transpiling your script. 然后我切换到使用完全相同的选项的编译脚本,它工作,所以我怀疑它与转换脚本有关。 The bad things is there's probably no easy way to check what code it generated. 糟糕的是,可能没有简单的方法来检查它生成的代码。

Anyway, the different types of imports are as follows: 无论如何,不​​同类型的进口如下:

  1. import {Observable} from 'rxjs/Rx'

    Since you're using baseURL option this will look for file node_modules/rxjs/Rx.js . 由于您正在使用baseURL选项,因此将查找文件node_modules/rxjs/Rx.js This is the entry point of RxJS that requires all Observables, Subjects, operator, so on... (about 300 files) and you'll import only Observable class. 这是RxJS的入口点,它需要所有Observables,Subjects,operator等等...(大约300个文件)并且你只导入Observable类。

  2. import Observable from 'rxjs/Observable'

    This imports only node_modules/rxjs/Observable.js file and its dependencies (about 20 files). 这只导入node_modules/rxjs/Observable.js文件及其依赖项(大约20个文件)。

  3. import Rx from 'rxjs/Rx'

    This shouldn't work at all. 这根本不起作用。 RxJS doesn't export any Rx . RxJS不会导出任何Rx You can see for yourself at src/Rx.ts 你可以在src/Rx.ts看看自己

If you're loading single files you can use similar config as this: 如果您正在加载单个文件,则可以使用类似的配置:

System.config({
  packages: {
    'src': {
      defaultExtension: 'js'
    },
    'rxjs': {
      defaultExtension: 'js'
    }
  },
  paths: {
    'npm:': 'node_modules/',
    'main': 'src/index'
  },
  map: {
    'rxjs': 'npm:rxjs'
  }
});

Then all imports are loaded as single files. 然后所有导入都作为单个文件加载。 For example rxjs/util/isFunction = /node_modules/rxjs/util/isFunction.js . 例如rxjs/util/isFunction = /node_modules/rxjs/util/isFunction.js

This isn't very useful in the browser because it'll be very slow. 这在浏览器中不是很有用,因为它会非常慢。 You can however load the bundled version with wildcard * . 但是,您可以使用通配符*加载捆绑的版本。 Note that this works only in SystemJS 0.19.*: 请注意,这仅适用于SystemJS 0.19。*:

System.config({
  packages: {
    'src': {
      defaultExtension: 'js'
    },
    'rxjs': {
      defaultExtension: 'js'
    }
  },
  paths: {
    'npm:': 'node_modules/',
    'main': 'src/index',
    'rxjs*': 'node_modules/rxjs/bundles/Rx.min.js'
  }

In SystemJS 0.20.* the wildcard * doesn't work any more ( https://github.com/systemjs/systemjs/issues/1039 ) 在SystemJS 0.20。*中,通配符*不再起作用( https://github.com/systemjs/systemjs/issues/1039

With this config you can use all: 使用此配置,您可以使用all:

import {Observable} from 'rxjs';
import {Observable} from 'rxjs/Observable';
import {Observable} from 'rxjs/Rx';

Note that the situation in node environment is different because you can always use just import {Observable} from 'rxjs' thanks to main option in its composer.json . 请注意, node环境中的情况不同,因为您可以始终使用import {Observable} from 'rxjs'这要归功于其composer.json main选项。

As I have the same issue on a project of mine, I've been trying to debug systemJs to understand. 由于我在我的项目中遇到同样的问题,我一直在尝试调试systemJs来理解。

Now I can tell that systemJS basically works like this: It transpile module files into setters and executes. 现在我可以告诉systemJS基本上是这样的:它将模块文件转换为setter并执行。 setters load dependencies and inject them into IIFE variables. setter加载依赖关系并将它们注入IIFE变量。 execute runs the module codes when the setters are all set. 当setter全部设置时,execute运行模块代码。 Those are what you wrote before transpile. 这些是你在转变之前写的。

(function(System, SystemJS) {System.register(["node_modules/rxjs/Subject.js"], function (_export, _context) {
    "use strict";

    var Subject;
    return {
        setters: [function (_node_modulesRxjsSubjectJs) {
            Subject = _node_modulesRxjsSubjectJs.Subject;
        }],
        execute: function () {
            class PetriNode {
                constructor(name) {
                    this.from = [];
                    this.to = [];

... ... ......

I found out that systemJS loads modules with this project 我发现systemJS用这个项目加载模块

within this line: line 612, the RxJs kinds of stuff and all load up fine. 在这一行:第612行,RxJs种类的东西,所有加载都很好。

      err = dynamicExecute(link.execute, require, moduleObj.default, module);

After executing, the module.exports and moduleObj.__useDefault is loaded perfectly fine. 执行后,module.exports和moduleObj .__ useDefault加载完全正常。 All the Rx Classes and outputs are there. 所有Rx类和输出都在那里。

But All The Defaults are FAILED to get COPIED into moduleObj as after this: 但是所有默认值都失败,以便在此之后将COPIED转换为moduleObj: 将默认值加载到moduleObj中

And then, when the setter is called, the inputted argument is moduleObj, which has a .default property has all the proper output, but setter failed to call them from but moduleObj itself. 然后,当调用setter时,输入的参数是moduleObj,它具有.default属性具有所有正确的输出,但是setter无法从moduleObj本身调用它们。 load.module没有导出的定义。这是load.module.default有它们。

The importerSetters is called the first time when all the Rx is done and begin to deal with my ECMA2015 modules. 当所有Rx完成并开始处理我的ECMA2015模块时,第一次调用importerSetters。 It's skipped every time when there is no import but requires. 每次没有导入但需要时都跳过它。

I don't understand how should I handle commonJS default with .d.ts with import. 我不明白我应该如何使用import来处理带有.d.ts的commonJS默认值。 I've seen that systemJS could deal with commonJS and ECMA2015 before. 我已经看到systemJS之前可以处理commonJS和ECMA2015。 I've done it independently but not together. 我是独立完成但不是一起完成的。

我遇到了类似的问题,设法取消阻止将我的tsconfig.json模块从“system”更改为“commonjs”,并且正在编译Rx lib文件而没有getter。

This appears to be a known issue. 这似乎是一个已知问题。

https://github.com/systemjs/systemjs/issues/334 https://github.com/systemjs/systemjs/issues/334

From the documentation ocumentation: 从文档ocumentation:

Any module type can be loaded from any other type with full support. 任何模块类型都可以从任何其他类型加载并完全支持。

When loading CommonJS, AMD or Global modules from within ES6, the full module is available at the default export which can be loaded with the default import syntax. 从ES6中加载CommonJS,AMD或Global模块时,默认导出中可以使用完整模块,可以使用默认导入语法加载。

For convenience, named exports are also auto-populated but may not be correctly bound as expected, so use these carefully. 为方便起见,命名导出也是自动填充的,但可能没有按预期正确绑定,因此请谨慎使用。

./app/es6-loading-commonjs: ./app/es6-loading-commonjs:

 // entire underscore instance import _ from './underscore.js'; // unbound named export import {map} from './underscore.js'; 

https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#inter-format-dependencies https://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#inter-format-dependencies

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM