Skip to content Skip to sidebar Skip to footer

How To Import `observable` From `rx` (not Angular)

I'm 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

Solution 1:

As it notes in the README, you can use 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; in your case, follow it with:

import'rxjs/add/observable/fromEvent';

Solution 2:

I was having exactly the same issue when transpiling from 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. 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.

  2. import Observable from 'rxjs/Observable'

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

  3. import Rx from 'rxjs/Rx'

    This shouldn't work at all. RxJS doesn't export any Rx. You can see for yourself at 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.

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.*:

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)

With this config you can use 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.

Solution 3:

As I have the same issue on a project of mine, I've been trying to debug systemJs to understand.

Now I can tell that systemJS basically works like this: It transpile module files into setters and executes. setters load dependencies and inject them into IIFE variables. execute runs the module codes when the setters are all set. Those are what you wrote before transpile.

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

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

... ...

I found out that systemJS loads modules with this project

within this line: line 612, the RxJs kinds of stuff and all load up fine.

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

After executing, the module.exports and moduleObj.__useDefault is loaded perfectly fine. All the Rx Classes and outputs are there.

But All The Defaults are FAILED to get COPIED into moduleObj as after this: load default into 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. load.module has no exported definitions. It's the load.module.default has them.

The importerSetters is called the first time when all the Rx is done and begin to deal with my ECMA2015 modules. 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. I've seen that systemJS could deal with commonJS and ECMA2015 before. I've done it independently but not together.

Solution 4:

I run into a similar problem, and managed to get unblocked changing my tsconfig.json module from "system" to "commonjs", and Rx lib files are being transpiled without getters.

Solution 5:

This appears to be a known issue.

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

From the documentation 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.

For convenience, named exports are also auto-populated but may not be correctly bound as expected, so use these carefully.

./app/es6-loading-commonjs:

// entire underscore instanceimport _ from'./underscore.js';

// unbound named exportimport {map} from'./underscore.js';

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

Post a Comment for "How To Import `observable` From `rx` (not Angular)"