Rollup: External RxJS when bundling an AMD module does not work.

Created on 6 Mar 2019  路  3Comments  路  Source: rollup/rollup

  • Rollup Version: 1.4.1
  • Operating System (or Browser): MacOS
  • Node Version: 10.10

How Do We Reproduce?

We have code that uses RxJS 6 within typescript, which is transpired by Rollup to a variety of package formats. One of these is ES5 / AMD. We do not wish to include RxJS in the module bundles and so we have marked it as external. All is well for iife, cjs and es.

In our code we import RXJS like this:

import {Observable}  from "rxjs";
import {filter} from "rxjs/operators";

In our rollup config:

{
    input: "some-file",
    external: [
      "rxjs",
      "rxjs/operators"
    ],
    output: [
    {
        file: "dist-internal/bundles/library.global.js",
        format: 'iife',
        name: "Library",
        sourcemap: true,
        globals: {
          "rxjs": "rxjs",
          "rxjs/operators": "rxjs.operators"
        }
      }, {
        file: "dist-internal/bundles/library.amd.js",
        format: 'amd',
        amd: {
          id: 'library'
        },
        name: "Library",
        sourcemap: true,
      },
       ... other ourputs.
    ]
}

We then run the build using:

rollup -c

Everything generates just fine.

Expected Behavior

We would expect it to be possible to somehow configure rollup such that our AMD module can work with RxJS's UMD module but this does not seem to be the case. We are not sure if this is an issue with Rollup or RxJS.

Actual Behavior

The AMD produced by rollup looks like this:

define(['exports', 'rxjs', 'rxjs/operators'], function (exports, rxjs, operators) {

As somewhat expected it is looking for the two external modules. However, looking here:

https://github.com/ReactiveX/rxjs/blob/master/doc/installation.md

The expectation is that all of RxJS is exported via a single global / module by the UMD. They expect you to use rxjs.Observable and rxjs.operators.filter. As you can see in our globals config for iife we have the ability to make that mapping, and thus it works just fine for iife. But for AMD there does not seem to be a way to achieve this. The AMD generated by rollup is looking for a module named rxjs/operators which is not going to exist anywhere.

It does seem like the real problem here is the inconsistent structure between the CommonJS / ES6 module and the UMD module for RxJS, but we are able to handle this for IIFE. Is there a way to handle this for UMD?

Thanks.

All 3 comments

In case anyone else comes across this, I was able to work around the issue to a degree doing this:

require.config({
  paths: {
    'rxjs': "https://unpkg.com/[email protected]/bundles/rxjs.umd.js"
  }
});

define("rxjs/operators", ["rxjs"], function (rxjs) {
  return rxjs.operators;
});

If there is a better way to do this in Rollup directly that would be ideal!

Hi, take a look at output.paths in the docs.
Don't know if it will work for umd modules (If it doesn't maybe just output in amd format if you can). If I remember correctly, output.globals option only works for iife modules and the iife part of umd ones.

For mapping rxjs operators automatically I don't think there's an easy way which doesn't involve writing a plugin. Give a try to rollup-plugin-virtual:

virtual({
  'rxjs/operators': `import rxjs from 'rxjs'; export default rxjs.operators;`
})

@isidrok Thanks for the tip! Here's what ultimately did the trick:

virtual({
  'rxjs/operators': `
     import rxjs from 'rxjs'; 
     export const {filter, map, concatMap, tap, share} = rxjs.operators;
  `
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Conduitry picture Conduitry  路  3Comments

iam-peekay picture iam-peekay  路  3Comments

adammockor picture adammockor  路  3Comments

otakustay picture otakustay  路  3Comments

jeffsaremi picture jeffsaremi  路  3Comments