How to import `Observable` from` Rx` (not angular)

I am using SystemJS to load my es2015 project into the browser.

This is what I did

import {Observable} from 'rxjs/Rx'; const button = document.querySelector('button'); const start$ = Observable.fromEvent(button, 'click'); 

In this case, the Observable is undefined . So I tried

 import Observable from 'rxjs/Observable'; 

In this case, Observable is an object, but Observable.fromEvent is undefined (it seems empty)

Finally i did

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

which really worked. Any ideas why the other two didn't work? I saw the code in which they used them. What would be the preferred way to import Observable ?

UPDATE: as indicated below, all of this is described in README . However, if I do,

 import { Observable } from 'rxjs/Observable'; import 'rxjs/add/observable/fromEvent'; const start$ = Observable.fromEvent(startButton, 'click'); 

I get Observable is undefined . And if I do

 import Observable from 'rxjs/Observable'; 

the Observable is an empty object. fromEvent not added.

I am using RxJs 5.1.1, and here is my part of 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> 
+5
source share
5 answers

As he notes in README , you can use import { Observable } from 'rxjs/Observable'; :

Import only what you need by fixing (this is useful for sorting by size)

This gives you a minimal Observable , for which you need to explicitly add any additional functionality that you plan to use; in your case follow it:

 import 'rxjs/add/observable/fromEvent'; 
+2
source

I had the same issue when passing from TypeScript. Then I switched to using only compiled scripts with exactly the same parameters, and it worked, so I'm suspicious that it has anything to do with forwarding your script. The bad things, there is probably no easy way to check which code it generated.

In any case, various types of imports:

  • import {Observable} from 'rxjs/Rx'

    Since you are using the baseURL parameter, this will look for the file node_modules/rxjs/Rx.js This is an RxJS entry point that requires all Observables, Subjects, operator and so on ... (about 300 files), and you import only the Observable class.

  • import Observable from 'rxjs/Observable'

    This only imports the node_modules/rxjs/Observable.js file and its dependencies (about 20 files).

  • import Rx from 'rxjs/Rx'

    This should not work at all. RxJS does not export any Rx . You can see for yourself src/Rx.ts

If you upload individual files, you can use a similar configuration:

 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 separate files. For example rxjs/util/isFunction = /node_modules/rxjs/util/isFunction.js .

This is not very useful in the browser because it will be very slow. However, you can download the bundled version using a wildcard * . Please note that this only works in 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. * wildcard * no longer works ( https://github.com/systemjs/systemjs/issues/1039 )

With this configuration you can use everything:

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

Note that the situation in the node environment is different in that you can always use only import {Observable} from 'rxjs' thanks to the main option in your composer.json .

+1
source

Since I have the same problem in my project, I tried to debug systemJs in order to understand.

Now I can say that systemJS basically works as follows: It converts module files to setters and executes them. set the loads on the bootloader and enter them into the IIFE variables. execution runs module codes when all setters are configured. This is what you wrote before the translation.

 (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 is loading modules with this project

in this line: line 612, views of RxJs and everything loads normally.

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

After execution, module.exports and moduleObj .__ useDefault loads completely fine. All classes and outputs of Rx are.

But all the default values ​​are FAULT to get COPIED in moduleObj, as after this: load default to moduleObj

And then, when the setter is called, the argument entered is moduleObj, whose .default property has all the correct output, but setter could not call them, but moduleObj itself. load.module has no exported definitions. They have load.module.default.

The ImportersSetters is called for the first time that all Rx runs and starts working with my ECMA2015 modules. It is skipped every time an import is not required, but is required.

I do not understand how I should handle defaultJS by default with .d.ts with import. I saw that the JS system could deal with commonJS and ECMA2015 before. I did it on my own, but not together.

+1
source

I had a similar problem and managed to unlock my tsconfig.json module from "system" to "commonjs", and Rx lib files are transferred without getters.

0
source

This is apparently a known issue.

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

From the documentation:

Any type of module can be loaded from any other type with full support.

When loading CommonJS, AMD, or Global modules from ES6, the full module is available by default export, which can be loaded using the default import syntax.

For convenience, the specified export is also automatically populated, but it may not be correctly linked as expected, so use them carefully.

./application/ES6-loader-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

0
source

Source: https://habr.com/ru/post/1264379/


All Articles