构造rxjs / Observable时出错

时间:2017-01-20 17:26:58

标签: rxjs systemjs typescript2.0

为什么以下TypeScript代码会编译,但是systemjs无法在运行时正确加载依赖项?

import React from 'react';

class Dashboard extends React.Component {
  render() {
    return <h1>Hello</h1>
  }
}

export default Dashboard;

然而,这有效:

import { Observable } from 'rxjs';
let temp123 = new Observable<String>();

具体来说,第一个代码会生成一个包含代码的.js文件:

import { Observable } from 'rxjs/Observable';
let temp123 = new Observable<String>();

但第二个代码生成了这个:

var Observable_1 = require('rxjs');
var temp123 = new Observable_1.Observable();

行require('rxjs')失败,出现404错误,因为那里没有文件。为什么typescript编译器能够解决这个问题,但是systemjs无法在运行时加载它?

还值得注意:只有在使用Observable进行某些操作时才会出现此问题。例如,以下代码有效:

var Observable_1 = require('rxjs/Observable');
var temp123 = new Observable_1.Observable();

我可以使用 Observable,并在其上调用方法,而不会在TypeScript编译器中生成require('rxjs')。但我无法构建一个,我也无法扩展它。

版本:TypeScript 2.0.3,Systemjs 0.19.27,rxjs 5.0.0-beta.12

1 个答案:

答案 0 :(得分:8)

  

为什么typescript编译器能够解决这个问题,但是systemjs   无法在运行时加载它?

它的工作方式:

撰写import { Observable } from 'rxjs';时,在rxjs node_modules中找到package.json "typings": "Rx.d.ts" 文件夹,其中包含rxjs

  export { Observable } from './Observable';

Observable.d.ts的类型声明文件,该文件包含

Observable

使得typescript在同一个文件夹Observable中找到另一个类型声明文件,该文件已导出Observable类的声明。

这足以使您的代码无错误地编译。

如果您的代码实际上没有尝试使用require('rxjs')作为值,那么它会起作用,因为typescript会unused reference elision - 如果package.json仅用于类型检查,就像在您的第二个例子,生成的javascrpt中没有main调用。

现在,SystemJS。

SystemJS没有任何默认位置来查找模块 - 它甚至不识别有 SystemJS.config({ paths: {'npm:': 'node_modules/'}, map: {'rxjs': 'npm:rxjs'}, packages: { rxjs: { } } }); 属性的rxjs/Observable文件的node_modules约定。

因此,您的示例中的SystemJS很可能是这样配置的:

import { Observable } from 'rxjs/Observable';

因此,此行导入的模块node_modules/rxjs/Observable.js

rxjs

映射到

map

因为paths前缀与node_modules/rxjs条目相匹配,后者与Observable一起将其映射到.js

rxjs部分按原样通过

添加了

rxjs扩展名,因为.js与systemjs config中的defaultExtension包匹配,对于属于某个包的任何模块,SystemJS会自动添加node_modules/rxjs/Observable.js扩展名,除非{ {1}}在该程序包配置中设置为其他内容。

它有效,因为文件node_modules/rxjs/Observable.d.ts存在。

该导入也适用于打字稿,因为import { Observable } from 'rxjs'; 也存在。

最后,这在运行时不起作用

node_modules/rxjs

因为它已映射到main网址,并且那里没有实际文件。

您可以使用SystemJS包配置中的 packages: { rxjs: { main: 'Rx.js' } } 属性来修复它:

node_modules/rxjs/Rx.js

现在它已映射到Observable,并且该文件实际存在并导出名为{{1}}的内容,因此它应该可以正常工作。

使用SystemJS 0.19.43,rxjs 5.0.3,typescript 2.1.5进行检查。