Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UMD bundle cannot be used for RxJS #9359

Closed
arpit-agarwal opened this issue Jun 20, 2016 · 111 comments
Closed

UMD bundle cannot be used for RxJS #9359

arpit-agarwal opened this issue Jun 20, 2016 · 111 comments
Labels
area: packaging Issues related to Angular's creation of npm packages type: bug/fix

Comments

@arpit-agarwal
Copy link

I'm submitting a ... (check one with "x")

[x] bug report
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question

Current behavior
I updated system-config.ts file to download umd file for rxjs I.e rxjs\bundles\Rx.umd.js. This worked. But I still see in dev tools a lot of individual JS being load like rxjs\observer.js

Expected/desired behavior
When using UMD for rxjs it should not download individual files

Reproduction of the problem
See this plunker when you riun in full screen mode observe the files being loaded in dev tools. http://plnkr.co/edit/TvjW2YK3NVJ7sDb7cHV4?p=preview

No community response on question: http://stackoverflow.com/questions/37881825/using-rxjs-umd-bundles

What is the expected behavior?
When using UMD for rxjs it should not download individual files

What is the motivation / use case for changing the behavior?
To reduce load request when angular app starting up

Please tell us about your environment:

  • Angular version: 2.0.0-rc.2
  • Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
    Tested only on chrome
  • Language: [all | TypeScript X.X | ES6/7 | ES5 | Dart]
    Tested with Typescript only
@dragGH102
Copy link

+1. I had the same issue

@vicb vicb changed the title UMD bundle cannot be sued for RxJS UMD bundle cannot be used for RxJS Jun 20, 2016
@arpit-agarwal
Copy link
Author

arpit-agarwal commented Jun 20, 2016

There are direct imports of Rx sub module in @anguard/http which may lead to this issue. If @angular/http start using rxjs from umd module then this could be resolved.

@IgorMinar IgorMinar added this to the 2.0.0-rc.3 milestone Jun 20, 2016
@IgorMinar
Copy link
Contributor

@robwormald this might a bigger issue than what I thought and is caused by deep imports into rxjs which won't work with umd. System.register format would handle this well, but that has other issues.

@pavandv
Copy link

pavandv commented Jun 22, 2016

One solution I came up with is that loading Rx.umd.js through script tag and removing all the entries related to RxJS from system-config.
This could resolve your issue.

@jalkanen
Copy link

@pavandv That solution does not seem to work; systemjs still attempts to load the individual script files.

@IgorMinar
Copy link
Contributor

@pavandv @jalkanen you'd have to access rxjs via window.Rx then, right?

@mlc-mlapis
Copy link
Contributor

Is there something new related to the problem with using RxJS bundle?

@gkgithub
Copy link

gkgithub commented Aug 1, 2016

Is there any workaround until the issue is fixed. I tried loading through script and delete all rxjs entries in systemjs file. Still, systemjs tries to download the individual rxjs operator files. Its impacting the initial load performance

@arpit-agarwal
Copy link
Author

You should use individual operators import (deep import). This will reduce the requests to 70-80 ( depending upon how heavily you use RxJS) from 275 by bundle like import

@robinkedia
Copy link

Hi - When can we expect a fix on this?

@rpaschoal
Copy link

@robinkedia,

It has a milestone related to RC5 upcoming release.

@fabricioferreira
Copy link

fabricioferreira commented Aug 4, 2016

I don't think it is worth to use the umd bundle anyway. It seems Rxjs folks have broken down the components into smaller pieces, then you need to explicitly reference what you want to use. This have reduced the amount of files being downloaded a lot from previous versions.

At my company I switched to a different approach, where I copy all the .js files from the npm folder into a vendor folder using a gulp task:

const source = './node_modules/rxjs/**/*.js';
const dest = './wwwroot/vendor/rxjs';
module.exports.dep = function (gulp, plugins) { return function () { return plugins.del(dest); }; };
module.exports.task = function (gulp, plugins) {
return function () {
return gulp.src(source)
.pipe(gulp.dest(dest));
};
};

And then map it using system.js.config:
var map = { ... 'rxjs': './vendor/rxjs' ... }

At first I didn't like the solution, but later it proved to be acceptable.

@awerlang
Copy link
Contributor

awerlang commented Aug 4, 2016

I don't think it is worth to use the umd bundle anyway. It seems Rxjs folks have broken down the components into smaller pieces, then you need to explicitly reference what you want to use. This have reduced the amount of files being downloaded a lot from previous versions.

Agreed. Loading individual files are only a problem in development mode with SystemJS loader. For production we bundle them into a single file for fast loading. But even if we get this to work (Rx UMD) we still have yet hundreds of files to deal with (on-the-fly typescript). So I believe the definitive answer for all of this is migration to webpack and angular-cli (I hope so).

TLDR: rxjs UMD is not helpful

@IgorMinar IgorMinar modified the milestones: 2.0.0-rc.5, 2.0.0-rc.6 Aug 9, 2016
@mhevery mhevery modified the milestones: 2.0.0-rc.6, 2.0.1 Aug 9, 2016
@steve3d
Copy link

steve3d commented Dec 17, 2016

@tigredonorte

try to use a relative path instead of npm: in bundles part.

@steve3d
Copy link

steve3d commented Dec 17, 2016

this is my system.config.js, works very well:

'use strict';

(function (global) {
    System.config({
        "defaultJSExtensions": true,
        // map tells the System loader where to look for things
        map: {
            // our app is within the app folder
            app: 'scripts',
            modules: 'scripts/modules',
            // angular bundles
            '@angular/core': 'assets/global/plugins/@angular/core/bundles/core.umd.min.js',
            '@angular/common': 'assets/global/plugins/@angular/common/bundles/common.umd.min.js',
            '@angular/compiler': 'assets/global/plugins/@angular/compiler/bundles/compiler.umd.min.js',
            '@angular/platform-browser': 'assets/global/plugins/@angular/platform-browser/bundles/platform-browser.umd.min.js',
            '@angular/platform-browser-dynamic': 'assets/global/plugins/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js',
            '@angular/http': 'assets/global/plugins/@angular/http/bundles/http.umd.min.js',
            '@angular/router': 'assets/global/plugins/@angular/router/bundles/router.umd.min.js',
            '@angular/forms': 'assets/global/plugins/@angular/forms/bundles/forms.umd.min.js',
            'moment': "assets/global/plugins/moment.min.js"
        },
        bundles: {
            "assets/global/plugins/Rx.min.js": [
                "rxjs/*",
                "rxjs/operator/*",
                "rxjs/observable/*",
                "rxjs/add/operator/*",
                "rxjs/add/observable/*",
                "rxjs/util/*"
            ]
        }
    });
})(this);

if it's not work for you, then, I'm pretty sure the problem is yours only. and try to update rxjs to rc.4, few things have changed after beta.12.

here is my spec:
angular 2.3.1
rxjs 5.0.rc4
systemjs 0.19.38
systemjs-builder 0.15.34

@Jan-M
Copy link

Jan-M commented Dec 19, 2016

@unlight thx - your solution works for me, too. But only if I do change my imports to use from 'rxjs/Rx'.

From a JS beginners perspective this is kind of a bummer as the Angular tutorial leads straight to Observables and the code does indeed work but one has to fiddle with this import/dependency.

@mlc-mlapis
Copy link
Contributor

mlc-mlapis commented Feb 3, 2017

Updated version of system.config.js config -> should be added line "rxjs/symbol/*" to:

bundles: {
            "assets/global/plugins/Rx.min.js": [
                "rxjs/*",
                "rxjs/operator/*",
                "rxjs/observable/*",
                "rxjs/add/operator/*",
                "rxjs/add/observable/*",
                "rxjs/symbol/*",
                "rxjs/util/*"
            ]
        }

for spec:

angular 2.4.6
rxjs 5.1.0
systemjs 0.19.46
systemjs-builder 0.16.2

@fredgate
Copy link

@mlc-mlapis Where does the file assets/global/plugins/Rx.min.js (declared in the bundles configuration of systemjs) come from ? Is it the file provided in the npm package, or is it a file rebuilt by yourself using SystemBuilder ?

@mlc-mlapis
Copy link
Contributor

The second is right. This is the file which represents the re-bundled version of RxJS. You can save it where you want. I am saving it at "assets/rxjs-bundle/Rx.min.js".

@JohnYoungers
Copy link

for the solutions that are using systemjs-builder, is part of the reason the compiled file is so large because the node_modules/rxjs/bundles folder is included, or do those files not impact the final result?

@guest73
Copy link

guest73 commented Mar 24, 2017

Tried everything out here. Nothing works for me.
Here is my structure:
app/
app.module.ts
...
node_modules/
your-own-path/
Rx.min.js
index.html
systemjs.config.js
...

I built the Rx.min.js as suggested.
Here is my systemjs.config.js

(function (global) {
    SystemJS.config({
        bundles: {

            "your-own-path/Rx.min.js": [
                "rxjs/*",
                "rxjs/operator/*",
                "rxjs/observable/*",
                "rxjs/add/operator/*",
                "rxjs/add/observable/*",
                "rxjs/symbol/*",
                "rxjs/util/*"
            ]
            
        },
        paths: {
            // paths serve as alias
            'npm:': 'node_modules/'
        },

        // map tells the System loader where to look for things
        map: {
            // our app is within the app folder
            app: 'app',

            // angular bundles
            '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
            '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
            '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
            '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
            '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
            '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
            '@angular/http/testing': 'npm:@angular/http/bundles/http-testing.umd.js',
            '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
            '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
            
            // other libraries
            'angular-tree-component': 'node_modules/angular-tree-component/dist/angular-tree-component.umd.js',
            //color picker
            'angular2-color-picker': 'node_modules/angular2-color-picker'

        },
        // packages tells the System loader how to load when no filename and/or no extension
        packages: {
            app: {
                main: './main.js',
                defaultExtension: 'js'
            },
            'angular2-color-picker': {
                main:'index.js',
                defaultExtension: 'js',
            }
        }
    });
})(this);

Here what I get as an output:
[1] 17.03.24 21:54:38 200 GET /your-own-path/Rx.min.js
[1] 17.03.24 21:54:39 404 GET /node_modules/systemjs/dist/Rx.min.js.map
[1] 17.03.24 21:54:39 404 GET /rxjs

What am I doing wrong?

@kylecordes
Copy link

@guest73 You can see the exact config I use to create a System bundle of RxJS here:

https://github.com/OasisDigital/rxjs-system-bundle

You can see it in use, here:

https://plnkr.co/edit/Fy0jvu?p=preview

Offhand, the main difference I see between my config and yours is a bit in the systemjs config:

    rxjs: {
      defaultExtension: false
    }

... but there could be something else also, of course.

@guest73
Copy link

guest73 commented Mar 26, 2017

Thanks @kylecordes, it kind of helped. The problem, seems to me, was in a way we referenced RxJS stuff in our own project.
There were 3 variants:

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

and also something like this

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

I removed the operator imports and made everything to be like import { Observable } from 'rxjs/Rx';
After this it started working.

@kylecordes
Copy link

@guest73 The problem with this form:

import { Observable } from 'rxjs/Rx';

is that it imports 'rxjs/Rx' itself, which problematically imports all of the operators - you can see that happen in the file easily online here:

https://unpkg.com/rxjs@5.2.0/Rx.js

I think the current "best" form to use is:

import { Observable } from 'rxjs/Observable';

This form:

  • Avoids importing all the operators - import just the ones you use, for minimum output size.
  • Is what I see most often "in the wild", and use in class materials (I teach Angular classes, among other things)
  • ... and is the form Angular itself uses, see:

https://github.com/angular/angular/search?utf8=%E2%9C%93&q=from+%27rxjs%2FObservable%27&type=

@steve3d
Copy link

steve3d commented Mar 27, 2017

please guys, this doesn't make any sense on a production build, you'll always use a bundler to build all scripts with aot, and trust me, I've spent 4 days to try to figure out how to use webpack and systemjs together, and still there are some problems, and after turning to @angular/cli, it only takes me about 15mins to make a aot bundles.

and with angular 4.0, it seems systemjs way won't work any more, I've tried with some different settings, and none of those works, and that take me a whole day, and with @angular/cli, it's really about just few keystrokes, then everything is done, dev build with sourcemap and watch, and production build with aot, everything works like a charm.

please guys, don't waste any more time on this, unless of course, you must stick to angular 2 version forever.

angular/cli is FAR MORE easier than this systemjs way.

Now in my setup, I use angular/cli to pack everything, and with systemjs to load any scripts dynamically, or just leave this work to angular/cli to pack a whole bunch of 3rd-party jquery plugins.

after move to angular/cli, my system.config.js only contains these

    SystemJS.config({
        // map tells the System loader where to look for things
        map: {
            jquery: 'assets/global/plugins/jquery.min.js'
        }
    });

@Tailslide
Copy link

Webpack worked for me as well. It took way less time to learn webpack from scratch and add it to my project than I spent trying to get systemjs bundling working

@abu7midan
Copy link

abu7midan commented Aug 15, 2017

the problem in bundles please copy this configjs or change it like this code

(function (global) {
    var map = {
        'app': 'app',

        // angular bundles
        '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
        '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
        '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
        '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
        '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
        '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
        '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
        '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',

        // other libraries
        'rxjs': 'npm:rxjs',
        'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js'
    };
    var packages = {
        'app': { main: 'main.js', defaultExtension: 'js' },
        'rxjs': { defaultExtension: 'js' },
    };
    var ngPackageNames = [
        'common',
        'compiler',
        'core',
        'forms',
        'http',
        'platform-browser',
        'platform-browser-dynamic',
        'router'
    ];
    // Individual files (~300 requests):
    function packIndex(pkgName) {
        packages['@angular/' + pkgName] = { main: 'index.js', defaultExtension: 'js' };
    }
    // Bundled (~40 requests):
    function packUmd(pkgName) {
        packages['@angular/' + pkgName] = { main: '/bundles/' + pkgName + '.umd.js', defaultExtension: 'js' };
    }
    // Most environments should use UMD; some (Karma) need the individual index files
    var setPackageConfig = System.packageWithIndex ? packIndex : packUmd;
    var config = {
        paths: {  'npm:': 'node_modules/'
        },
        map: map,
        packages: packages
    };
    System.config(config);
})(this);
`


its will works perfectly

@TsengSR
Copy link

TsengSR commented Aug 16, 2017

@abu7midan: How is that going to help?

The systemjs loader will stick pick up the single files instead of the bundle in single request to the Rx.umd.js, which results anywhere between 80 and 150 additional requests to the server. And this happens in any non trivial case where you import rxjs/Rx.

@jeshcalls
Copy link

Thank you for this information. I was using the bundled rxjs without any issues. Today wanted to use angular material and when I use that, i get error,
http://localhost:8000/rxjs as "rxjs" from http://localhost:8000/node_modules/@angular/material/bundles/material.umd.js

@mlc-mlapis
Copy link
Contributor

@jeshcalls ... can you show the exact error message?

@jeshcalls
Copy link

Please find the error below.

ERROR Error: Uncaught (in promise): Error: Error: XHR error (404 Not Found) loading http://localhost:8000/rxjs
at XMLHttpRequest.wrapFn [as _onreadystatechange] (http://localhost:8000/node_modules/zone.js/dist/zone.js:636:29)
at ZoneDelegate.invokeTask (http://localhost:8000/node_modules/zone.js/dist/zone.js:225:37)
at Object.onInvokeTask (http://localhost:8000/node_modules/@angular/core/bundles/core.umd.js:3913:33)
at ZoneDelegate.invokeTask (http://localhost:8000/node_modules/zone.js/dist/zone.js:224:42)
at Zone.runTask (http://localhost:8000/node_modules/zone.js/dist/zone.js:125:47)
at XMLHttpRequest.ZoneTask.invoke (http://localhost:8000/node_modules/zone.js/dist/zone.js:293:33)
Error loading http://localhost:8000/rxjs as "rxjs" from http://localhost:8000/node_modules/@angular/material/bundles/material.umd.js

@mlc-mlapis
Copy link
Contributor

@jeshcalls ... it means that there is nothing on URL http://localhost:8000/rxjs

What loader are you using? SystemJS?

@jeshcalls
Copy link

yeah I am using SystemJS, when I add a map entry in System.config.js to have rxjs: npm:rxjs, it is fetching from http://localhost:8000/node_modules/rxjs which has the folder but obviously individual js files of rxjs is fetched.

@mlc-mlapis
Copy link
Contributor

mlc-mlapis commented May 22, 2018

@jeshcalls ... for re-bundled RxJS 5.5.x you should have the following if your systemjs.config.js, where assets/rxjs-bundle/Rx.min.js is the re-budled RxJS file:

bundles: {
        ...,
	"assets/rxjs-bundle/Rx.min.js": [
		"rxjs/*",
		"rxjs/operator/*",
		"rxjs/operators/*",
		"rxjs/observable/*",
		"rxjs/add/operator/*",
		"rxjs/operators/*",
		"rxjs/add/observable/*",
		"rxjs/scheduler/*",
		"rxjs/symbol/*",
		"rxjs/util/*"
	],
        ...
}

@TsengSR
Copy link

TsengSR commented May 22, 2018

@jeshcalls: SystemJS is dead. Angular moved away from it long ago to webpack and angular-cli now

@jeshcalls
Copy link

@mlc-mlapis : Thanks so much. I read through your previous posts on this and missed this. This bundle did not work but I added a map attribute as 'rxjs': 'npm:./tmp/Rx.js' and it worked.

@jeshcalls
Copy link

@TsengSR : You are absolutely right. Is there a web link that compares the system js and webpack modes. Have to show a consolidated presentation to my bosses to make them agree to make the shift.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: packaging Issues related to Angular's creation of npm packages type: bug/fix
Projects
None yet
Development

No branches or pull requests