RxJS 5.5进行了重大改变,并引入lettable operators来代替我们之前使用过的所有运算符(称为“补丁”运算符)。
那篇文章包含一个注释:
现在可以从rxjs /运算符导入Lettable运算符,但这样做 所以不改变你的构建过程往往会导致更大的 应用程序包。这是因为默认情况下rxjs /运算符会 解析为rxjs的CommonJS输出。
此声明很容易通过全新的AngularCLI生成的应用程序来证明。
当我们有一个不从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);
});
}
}
我们可以看到以下内容:
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运算符并使用它时:
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);
});
}
}
我们看不到捆绑大小的增加:
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运算符时,而不是修改构建过程:
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还没有被树木震动:
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]
当我尝试按照文章No Control over Build Process
部分的建议导入lettable运算符时:
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
更新:套餐版本(目前基本上都是AngularCLI应用的最新“通缉”版本):
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
答案 0 :(得分:2)
为完整起见,@ angular / cli @ 1.4.9在 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
所以第一个映射干扰了第二个映射。
通过颠倒构建的映射顺序,我认为错误在于rxjs v5.5。
也就是说,亚历山大的解决方案是解决问题的途径。
答案 1 :(得分:1)
确保您至少使用5.5.0
。否则检查文件node_modules/rxjs/operators/map.js
是否存在,因为我不知道它怎么可能不存在。另外使用import { map } from "rxjs/operators";
导入下面的相同文件,所以我怀疑你的构建系统有问题。
使用运算符的正确方法是从rxjs/operators/*
导入它们(例如,与import { map } from "rxjs/operators/map";
一样)。
如果您从rxjs/operators
导入,则与从RxJS中的rxjs
导入< 5.5.0,因为您实际上是导入rxjs/operators/index
,请参阅https://github.com/ReactiveX/rxjs/blob/master/src/operators/index.ts。
这就是为什么它没有“树摇动”,它导入了index.ts
中列出的所有运营商。
答案 2 :(得分:1)
事实证明(归功于 @RichardMatsen ),这是angular-cli 1.4.9
中的错误。
使用import { map } from "rxjs/operators/map";
尝试深度导入(例如angular-cli 1.4.8
),没有构建错误,并且包大小为:
chunk {0} polyfills.e1f97a0070e18e96a6be.bundle.js (polyfills) 61.4 kB {4} [initial] [rendered]
chunk {1} main.d36cf6834f640163ff35.bundle.js (main) 4.97 kB {3} [initial] [rendered]
chunk {2} styles.d41d8cd98f00b204e980.bundle.css (styles) 0 bytes {4} [initial] [rendered]
chunk {3} vendor.658e9efd9845db281b29.bundle.js (vendor) 241 kB [initial] [rendered]
chunk {4} inline.c9d245ca6c859aaeef69.bundle.js (inline) 1.45 kB [entry] [rendered]
与不使用RxJS运算符的版本相比,它只显示5 kB增益。
所以现在,我们至少有一个解决方法:留在angular-cli 1.4.8
并导入具有深度导入的lettable operatirs,如:
import { map } from "rxjs/operators/map";
import { filter } from "rxjs/operators/filter";