Importing lettable RxJS operators

百般思念 提交于 2019-11-28 09:29:56

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
    },

and rxjs/_esm5/path-mapping.js has these two entries

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

The essential bit of the error message is

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.

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.

  1. Make sure you're really using at least 5.5.0. Otherwise check that file node_modules/rxjs/operators/map.js exists because I don't know how could it not. Also using import { map } from "rxjs/operators"; imports the same file underneath so I'd suspicious there's something wrong with your build system.

  2. The correct way to use operators is to import them form rxjs/operators/* (for example like you did with import { map } from "rxjs/operators/map";).

    If you import from rxjs/operators it's the same like importing from rxjs in RxJS < 5.5.0 because you're in fact importing rxjs/operators/index, see https://github.com/ReactiveX/rxjs/blob/master/src/operators/index.ts.

    That's why it didn't get "tree-shaken", it imported all operators listed in index.ts.

As it turned out (credits to @RichardMatsen), it's a bug in angular-cli 1.4.9.

Trying deep imports (like import { map } from "rxjs/operators/map";) with angular-cli 1.4.8, there is no build errors and bundle sizes are:

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]

Which shows only 5 kB gain compared to the version that doesn't use RxJS operators at all.

So for now, we have at least a workaround: stay on angular-cli 1.4.8 and import lettable operatirs with deep imports like:

import { map } from "rxjs/operators/map";
import { filter } from "rxjs/operators/filter";
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!