jspm / project

Roadmap and management repo for the jspm project
161 stars 8 forks source link

RxJS 6 #38

Closed nicholasstephan closed 6 years ago

nicholasstephan commented 6 years ago

RxJS, as of version 6, recommends you import constructors and operators like this:

import { Observable, Subject, ReplaySubject, from, of, range } from 'rxjs';
import { map, filter, switchMap } from 'rxjs/operators';

But if I try to do that in the browser with:

import { Observable, Subject, ReplaySubject, from, of, range } from 'https://dev.jspm.io/rxjs@6';
import { map, filter, switchMap } from 'https://dev.jspm.io/rxjs@6/operators';

I get errors along these lines:

Uncaught SyntaxError: The requested module 'https://dev.jspm.io/rxjs@6/operators' does not provide an export named 'map'

I can get around it by importing the whole rxjs module and teasing out what I need, like I would using a CDN:

import rxjs from 'https://dev.jspm.io/rxjs@6';
const { Observable } = rxjs;
const { map } = rxjs.operators;

but this defeats what the Rx team is trying to do to decrease the final bundle size, etc.

I'm sure this isn't just an RxJS problem.

What is the solution here moving forward to get our dev javascript (imports directly into the browser) to look like what we'd finally want to pass to a bundler?

guybedford commented 6 years ago

It's great you're showing an interest in the forwards-compatibility here. The way that ES modules interop with CommonJS is dictated here by the NodeJS interop pattern, as it gets to set the precedent here.

Currently when running NodeJS with --experimental-modules and a main.mjs importing just like you provided you will get this same behaviour.

NodeJS treats all CommonJS modules as a module with the shape - { default: require('x') }.

There has been much discussion (and this is still ongoing) about reading the iterable keys off the module and making them available as named exports. But this hits a spec violation in that getting the iterable exports of a module object requires first executing the CommonJS module, while the ES module specification explicitly states that modules must know their exports before they are executed. This has gone back to TC39 a number of times over the years to try and release this constraint, but again it is still an ongoing problem.

For now we know that we will at least get the default being provided regardless. And there may come some solutions to the named exports problems, but they can't be assumed right now.

To follow along further the NodeJS interop processes are being discussed further at https://github.com/nodejs/modules/.