如何在不需要 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:音频在某些情况下只会播放一次