导入lettable RxJS运算符 [英] Importing lettable RxJS operators

查看:115
本文介绍了导入lettable RxJS运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RxJS 5.5进行了重大改变,并引入了可租赁运营商基本上替换我们之前使用过的所有运算符(称为补丁运算符)。

RxJS 5.5 makes a big breaking change and introduces lettable operators to replace basically all operators (called "patch" operators) we used to use before.

该文章包含一个注释:


现在可以从rxjs /运算符,但是在不改变构建过程的情况下执行
通常会导致更大的
应用程序包。这是因为默认情况下rxjs /运算符将
解析为rxjs的CommonJS输出。

Lettable operators can now be imported from rxjs/operators, but doing so without changing your build process will often result in a larger application bundle. This is because by default rxjs/operators will resolve to the CommonJS output of rxjs.

此语句很容易证明使用全新的AngularCLI生成的应用程序进行练习。

This statement is easy to proof on the practice with the brand new AngularCLI-generated app.

当我们有一个不从RxJS导入任何内容的应用程序时:

When we have an application that doesn't import anything from RxJS:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public title = 'app';

  constructor(private readonly http: HttpClient) {
  }

  public ngOnInit(): void {
    this.http.get('https://api.github.com/users')
      .subscribe(response => {
        console.log(response);
      });
  }
}

我们可以看到以下内容:

We can see the following:

ng build --prod
chunk {0} polyfills.e1f97a0070e18e96a6be.bundle.js (polyfills) 61.4 kB {4} [initial] [rendered]
chunk {1} main.b2b5d212102ca9d103e8.bundle.js (main) 4.92 kB {3} [initial] [rendered]
chunk {2} styles.d41d8cd98f00b204e980.bundle.css (styles) 0 bytes {4} [initial] [rendered]
chunk {3} vendor.4b7be3dbe842aec3f0ab.bundle.js (vendor) 236 kB [initial] [rendered]
chunk {4} inline.387c7023e5627ac04221.bundle.js (inline) 1.45 kB [entry] [rendered]

当我们导入一个RxJS运算符时旧的方式并使用它:

When we import a RxJS operator the "old" way and use it:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import "rxjs/add/operator/map";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public title = 'app';

  constructor(private readonly http: HttpClient) {
  }

  public ngOnInit(): void {
    this.http.get('https://api.github.com/users')
      .map((u: any) => 1)
      .subscribe(response => {
        console.log(response);
      });
  }
}

我们看到捆绑包的大小没有增加:

We can see no gain in size of bundles:

chunk {0} polyfills.e1f97a0070e18e96a6be.bundle.js (polyfills) 61.4 kB {4} [initial] [rendered]
chunk {1} main.229ad10195bbb426b3e8.bundle.js (main) 4.96 kB {3} [initial] [rendered]
chunk {2} styles.d41d8cd98f00b204e980.bundle.css (styles) 0 bytes {4} [initial] [rendered]
chunk {3} vendor.933334fc50e7008778fe.bundle.js (vendor) 236 kB [initial] [rendered]
chunk {4} inline.6a52179d8b19cd3cc179.bundle.js (inline) 1.45 kB [entry] [rendered]

当我们尝试导入并使用lettable运算符时但是没有修改构建过程:

When we try to import and use the lettable operator instead as recommended but without modifying the build process:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from "@angular/common/http";
import { map } from "rxjs/operators";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  public title = 'app';

  constructor(private readonly http: HttpClient) {
  }

  public ngOnInit(): void {
    this.http.get('https://api.github.com/users').pipe(
        map((u: any) => 1))
      .subscribe(response => {
        console.log(response);
      });
  }
}

我们看到供应商捆绑包大了108 kB告诉我们RxJS还没有被树木震动:

We see that the vendor bundle is 108 kB bigger which tells us that RxJS hasn't been tree-shaked:

chunk {0} polyfills.e1f97a0070e18e96a6be.bundle.js (polyfills) 61.4 kB {4} [initial] [rendered]
chunk {1} main.450c741a106157402dcd.bundle.js (main) 4.97 kB {3} [initial] [rendered]
chunk {2} styles.d41d8cd98f00b204e980.bundle.css (styles) 0 bytes {4} [initial] [rendered]
chunk {3} vendor.3f53f0e2283f4c44ec38.bundle.js (vendor) 344 kB [initial] [rendered]
chunk {4} inline.2d973ef5a10aa806b082.bundle.js (inline) 1.45 kB [entry] [rendered]

当我尝试按照文章中无控制生成过程部分的建议导入lettable操作符时:

When I try to import the lettable operator as recommended in the No Control over Build Process section of the article:

import { map } from "rxjs/operators/map";

我收到了构建错误:

./src/app/app.component.ts
Module not found: Error: Can't resolve 'rxjs/operators/map' in 'c:\Projects\Angular\src\app'
 @ ./src/app/app.component.ts 14:0-41
 @ ./src/app/app.module.ts
 @ ./src/main.ts
 @ multi webpack-dev-server/client?http://localhost:4200 ./src/main.ts




  1. 我做错了什么?

  2. 我们如何导入新的RxJS可投放运营商一个Angular CLI app
    这样RxJS仍然会被树木震动?

UPDATE:软件包版本(基本上所有版本都是AngularCLI应用程序的最新通缉版本):

UPDATE: Package versions (basically all are latest "wanted" versions of an AngularCLI app at the moment):

rxjs: 5.5.0
@angular/cli: 1.4.9
node: 8.6.0
os: win32 x64
@angular/animations: 4.4.6
@angular/common: 4.4.6
@angular/compiler: 4.4.6
@angular/core: 4.4.6
@angular/forms: 4.4.6
@angular/http: 4.4.6
@angular/platform-browser: 4.4.6
@angular/platform-browser-dynamic: 4.4.6
@angular/router: 4.4.6
@angular/cli: 1.4.9
@angular/compiler-cli: 4.4.6
@angular/language-service: 4.4.6
typescript: 2.3.4


推荐答案

为了完整性, @ angular / cli @ 1.4.9在 models / webpack-configs / common.js中添加以下内容

For completeness, @angular/cli@1.4.9 adds the following in models/webpack-configs/common.js

// Read the tsconfig to determine if we should prefer ES2015 modules.
// Load rxjs path aliases.
// https://github.com/ReactiveX/rxjs/blob/master/doc/lettable-operators.md#build-and-treeshaking
let alias = {};
try {
    const rxjsPathMappingImport = 'rxjs/_esm5/path-mapping';
    const rxPaths = require_project_module_1.requireProjectModule(projectRoot, rxjsPathMappingImport);
    alias = rxPaths(nodeModules);
}
catch (e) { }

    resolve: {
        extensions: ['.ts', '.js'],
        modules: ['node_modules', nodeModules],
        symlinks: !buildOptions.preserveSymlinks,
        alias
    },

rxjs / _esm5 / path-mapping.js 有这两个条目

"rxjs/operators": path.resolve(PATH_REPLACEMENT, "rxjs/_esm5/operators/index.js"),
...
"rxjs/operators/map": path.resolve(PATH_REPLACEMENT, "rxjs/_esm5/operators/map.js"),

基本位错误消息是

aliased with mapping 'rxjs/operators': 
  'C:\Dev\Projects\rx55\node_modules\rxjs\_esm5\operators\index.js' to 
  'C:\Dev\Projects\rx55\node_modules\rxjs\_esm5\operators\index.js/map'
...
C:\Dev\Projects\rx55\node_modules\rxjs\_esm5\operators\index.js\map doesn't exist

所以第一个映射干扰第二个映射。

so the first mapping is interfering with the second.

通过颠倒构建的映射顺序,我想我的错误是rxjs v5.5。

By reversing the order of the mappings the build works, so to my mind the fault is with rxjs v5.5.

也就是说,亚历山大的解决方案是修复前的路径。

That said, Alexander's work-around is the path to take until the fix.

这篇关于导入lettable RxJS运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆