RxJS version:
6.2.0
Code to reproduce:
Can't provide
Expected behavior:
Expect the output file size to be the same size as v5 or smaller.
Actual behavior:
Output rxjs is about 4x larger
Additional information:
I have a TypeScript project that I build with webpack, emitting ES5 ultimately, and performs ES6 tree shaking via Babel. It currently uses v5 of RXJS, utilizing AsyncSubject, Observable, ReplaySubject, BehaviorSubject and several operators like bufferTime, filter, and others.
When looking at the output from the webpack-bundle-analyzer, below, I see that the parsed size of my output is 27.13 KB. I updated my project to utilize rxjs6 without using the compatibility library and re-built it with the same build pipeline. This time I got an output size of 116.43 KB, which is more than 4x larger. This primarily looks like it's because of whatever is in this _esm5 directory, but this alone preempts my adoption of v6.
What can be done to shrink this directory (or better, eliminate it so I can achieve sizes as small as what I got with v5)?
Thanks!
rxjs5
rxjs6
This seemingly looks like related with configuration / how to import modules around, but we can't figure out without reproducible code (or config and other environment surroundings). Curious if you already applied all suggestions at https://github.com/ReactiveX/rxjs/blob/d231053616ab4e5d2541818314110df626e6bf5a/doc/pipeable-operators.md#build-and-treeshaking .
@kwonoj I didn't see that document originally when I was reading through the documentation. I'll work through the suggestions there and get back to you.
@kwonoj I checked your solutions but none of them seems to work as I expected, bundle size keeps almost the same. I don't know why Rxjs 6 drops the support for something like:
import { switchMap } from 'rxjs/operators/switchMap';
This solution is flexible and adds control over your dependencies.
Even if use rxjs-compat package to allow me to do that, the bundle size almost equal in size.
agreed , seeing same issues. this is thie biggest bundle size in my vendor chunk.
All I am using is these
import { mergeMap, delay, map, catchError } from 'rxjs/operators';
import { of, concat } from 'rxjs';
import {
ActionsObservable,
StateObservable,
ofType,
combineEpics,
} from 'redux-observable';
"redux-observable": "1.0.0",
"rxjs": "6.2.2",
and i have a bundle size of 167 KB parsed size, from rxjs lib alone. every operator is in the bundle
Using version 6.2.2 and seeing the same issue myself. I've tried following the documentation on tree shaking as linked to above but it has made no difference.
When seen through bundle analyzer, I also see every single operator included in the bundle when only importing a single operator from 'rxjs/operators' and nothing else, as a trivial test case.
Example code:
index.js
import {filter} from 'rxjs/operators';
webpack.config.js
const config = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, '../../dist')
},
mode: 'production',
resolve: {
alias: rxPaths()
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
},
plugins: [
new webpack.optimize.ModuleConcatenationPlugin()
]
};
Bundle analyzer visualisation looks exactly like the OP's screenshot. Adding the rxPaths() alias, ModuleConcatenationPlugin() seems to make no different to what's included or the bundle size.
@patrickkunkadazn I tried your snippet and created https://github.com/kwonoj/rxjs-webpack-test , npm run build do wepback and output is


8kb in total. Rxjs is 6.2.2, as same as you mentioned: https://github.com/kwonoj/rxjs-webpack-test/blob/master/package.json#L15
Hmm interesting my output is 292kb / 99kb minified. Thanks for creating the repo - I will scan for differences now.
@patrickkunkadazn worth to share your repo as well, so anyone can try and dig differences.
So it looks like this is caused by the presence of the babel-preset-env package:
https://github.com/patrickkunkadazn/rxjs-webpack-test
I've added the package, and also a .babelrc file. Now the entirety of RxJS 6 is included when built. Perhaps this is the expected behaviour, but it would be good to understand why.
@kwonoj would you like me to open a separate issue for this?
I had a look through every babel plugin that was being included with preset-env that could be breaking treeshaking, and eventually narrowed it down to this one:
https://www.npmjs.com/package/babel-plugin-transform-es2015-modules-commonjs
Without this plugin present, tree shaking works, but with it present, we end up including the whole library.
I think that's expected, if import syntax is transpiled into cjs require, there's no way to make tree shaking work.
OK - I assumed as much. Considering using babel-preset-env is part of the standard workflow of someone writing in modern javascript and transpiling to ES5 or similar for production, should this be flagged in the documentation somewhere?
From what I understand, and from my testing, we can simply remove this plugin from preset-env, and
import statements and convert to an ES5-compatible bundle anywayI'm assuming this is the root cause of the issues described by the other commenters in this issue, so probably worth flagging?
If all others in this issue experiences same due to config, I think it's worth to write up document. Probably need confirmation.
Cool, in the mean time – here's the fix:
.babelrc
{
"presets": [
["env", {
"modules": false
}]
]
}
In TypeScript, the equivalent would be to set compilerOptions.module to 'esnext', so that webpack can see the import statements.
I'm going to close this as it's answered for some aspect and do not have additional cases other then configuration issue. We may update documentation for precaution later.
I've been running into this issue and the suggestions above with setting modules: false in Babel configs don't seem to work in the Babel 7.x world.
Most helpful comment
Cool, in the mean time – here's the fix:
.babelrc
In TypeScript, the equivalent would be to set
compilerOptions.moduleto'esnext', so that webpack can see theimportstatements.