如何在不需要 rxjs-compat 的情况下只导入 RxJS 6 中使用的运算符,如旧的 RxJS?

Posted

技术标签:

【中文标题】如何在不需要 rxjs-compat 的情况下只导入 RxJS 6 中使用的运算符,如旧的 RxJS?【英文标题】:How to import only used operators in RxJS 6 like older RxJS without requiring rxjs-compat? 【发布时间】:2018-10-29 03:42:55 【问题描述】:

以前我只能使用此代码导入使用过的运算符:

import 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/finally';
import 'rxjs/add/observable/empty';
import 'rxjs/add/observable/throw';

这会生成一个小包 (vendor.ts)。 如何在不需要 rxjs-compat 的情况下使用 RxJS 做到这一点? 将上面的代码更改为 import 'rxjs'; 会生成一个更大的包。

更新:

我遵循了您发布的所有答案,但没有任何效果。 这是我更新的 vendor.ts:

import 'rxjs/Observable';
import 'rxjs/Subscription';
import 'rxjs/Subject';
import 'rxjs/observable/throw';
import 'rxjs/operators/map';
import 'rxjs/operators/mergeMap';
import 'rxjs/operators/catchError';
import 'rxjs/operators/finalize';

我也尝试过使用 'rxjs/add/operator/*'。

这就是我导入 rxjs 的方式:

import Observable from 'rxjs/Observable';
import Subscription from 'rxjs/Subscription';
import Subject from 'rxjs/Subject';
import _throw from 'rxjs/observable/throw';
import map from 'rxjs/operators/map';
import mergeMap from 'rxjs/operators/mergeMap';
import catchError from 'rxjs/operators/catchError';
import finalize from 'rxjs/operators/finalize';   

我根据此文档 (https://github.com/ReactiveX/rxjs/blob/master/doc/pipeable-operators.md#build-and-treeshaking) 更改了我的 Webpack 3 配置,但没有任何效果。

最后,看看 Webpack Bundle Analyzer 的结果:

捆绑包包括所有运算符。 我发现了这个相关的问题: https://github.com/angular/angular-cli/issues/9069

【问题讨论】:

rxjs-compat 正是为此目的而设计的。 @estus,但是这个库不只是用来保持与旧版本的兼容性吗?如何以新的方式使用它?没有 rxjs-compat 这不存在吗? 这就是它提供与旧版本兼容的方式。通过提供旧的导入样式。 @estus,但如何只使用新的方式,但减少供应商规模? 与使用 RxJS 5 的方式相同。***.com/questions/42376972/… 。 rxjs-compat 需要安装,但不需要require 【参考方案1】:

rxjs-compat应该和rxjs一起安装,它提供了对旧式导入的支持。

可以像使用 RxJS 5 一样使用 RxJS 6:

import 'rxjs/add/operator/map';
import  Observable  from 'rxjs/Observable';

这个兼容层预计会在 RxJS 7 中被移除。

【讨论】:

使用这种方式会导致更小的包? 这与 RxJS 5 中的相同。从 rxjs/Observable 导入 Observable 是如何完成的(不是从 rxjs/Rx,永远不会从 import 'rxjs' 因为省略 from 导致完全导入包)。 请检查我在问题中的更新。一切正常。 我猜这个问题可能与您的构建有关,而不是 RxJS。是的,问题可能出在 Webpack 中。通常使用 RxJS 6 作为 Angular 6 的先决条件。为什么要使用 Webpack 3?您是否尝试切换到 4? 过去我很头疼要切换到 Webpack 4,但我现在正在尝试更新。【参考方案2】:

对我来说,问题是我在 tsconfig.json 中将 module 设置为 commonjs。它需要设置为es6,因为 webpack 需要 es6 模块才能使其能够进行摇树。

查看更多信息:https://webpack.js.org/guides/tree-shaking/

Tree Shaking 是 javascript 上下文中常用的一个术语 死代码消除。它依赖于 ES2015 的静态结构 模块语法,即导入和导出...

...

使用 ES2015 模块语法(即导入和导出)。 确保没有编译器将您的 ES2015 模块语法转换为 CommonJS 模块

【讨论】:

【参考方案3】:

现在您需要导入您想要使用的函数。

永远不要使用

从“rxjs”导入

与解构一起使用

从 'rxjs' 导入 Observable

'rxjs/operators'导入运算符

来自'rxjs'的静态函数

因此,例如,您需要使用 operator 'map' 来导入它

import  map  'rxjs/operators';

然后你将它与管道一起使用

observable.pipe(map(() =>  some function ))

为了更好地理解,请阅读Migration Guide 或观看来自ng-conf 的精彩视频

【讨论】:

我用的是这种方式,但是问题是所有的操作符都会包含在最终的bundle中。 如果你使用 import 'rxjs';是的,但你应该使用 import operator from 'rxjs/operators' 请检查我在问题中的更新。一切正常。 @SandroSimas 在您的更新中表明您在vendor.ts 文件中仍然有各种其他类型的 rxjs 导入。您还使用旧的 (RxJS 5) 方式导入运算符。这个答案其实是正确的。您可能应该从 vendor.ts 文件中删除对 rxjs 的任何引用,并在整个应用程序中修改您的导入。【参考方案4】:

您只需要这两部分代码:

Import  filter, map  from "rxjs/operators"

在此列表中,您可以添加任何需要使用的运算符。

Import  Observable  from "rxjs" 

【讨论】:

以上是关于如何在不需要 rxjs-compat 的情况下只导入 RxJS 6 中使用的运算符,如旧的 RxJS?的主要内容,如果未能解决你的问题,请参考以下文章

node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10) 中的错误:

node_modules/rxjs-compat/operator/shareReplay.d.ts(2,10) 中的错误:错误 TS2305:

JavaScript + HTML5:音频在某些情况下只会播放一次

EJS 在某些情况下只输出第一个找到的用户

如何在不需要额外点击的情况下使 DataGridCheckBoxColumn 可编辑?

如何在不需要 ENTER 的情况下接收键输入? [复制]