gpt4 book ai didi

javascript - 导入可出租的 RxJS 运算符

转载 作者:太空狗 更新时间:2023-10-29 17:51:44 26 4
gpt4 key购买 nike

RxJS 5.5 做出重大改变并引入了 lettable operators基本上替换我们以前使用的所有运算符(称为“补丁”运算符)。

那篇文章包含一个注释:

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 生成的应用程序中得到实践证明。

当我们有一个不从 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);
});
}
}

我们看不到 bundle 大小的增加:

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);
});
}
}

我们看到 vendor bundle 大了 108 kB,这告诉我们 RxJS 还没有经过 tree-shaking:

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
  1. 我做错了什么?
  2. 我们如何在 Angular CLI 应用程序中导入新的 RxJS 可出租运算符这样 RxJS 仍然可以进行 tree-shaking?

更新: 包版本(基本上都是目前 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

最佳答案

为了完整性,@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 上。

也就是说,Alexander 的解决方法是解决问题之前要采取的方法。

关于javascript - 导入可出租的 RxJS 运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46853898/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com