构造rxjs/Observable时出错

构造rxjs/Observable时出错,rxjs,systemjs,typescript2.0,Rxjs,Systemjs,Typescript2.0,为什么要编译下面的TypeScript代码,但systemjs无法在运行时正确加载依赖项 import { Observable } from 'rxjs'; let temp123 = new Observable<String>(); 但第二个代码生成了以下内容: var Observable_1 = require('rxjs/Observable'); var temp123 = new Observable_1.Observable(); 行require('rxjs'

为什么要编译下面的TypeScript代码,但systemjs无法在运行时正确加载依赖项

import { Observable } from 'rxjs';
let temp123 = new Observable<String>();
但第二个代码生成了以下内容:

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

import { Observable } from 'rxjs';
let temp123 = new Observable<String>();
同样值得注意的是:这个问题只有在我使用可观察的对象做某些事情时才会发生。例如,以下代码起作用:

import { Observable } from 'rxjs';
let temp123: Observable<String> = null;
let xyz = temp123.first();
从'rxjs'导入{Observable};
设temp123:Observable=null;
设xyz=temp123.first();
我可以使用Observable并对其调用方法,而无需TypeScript编译器生成require('rxjs')。但我不能构造一个,也不能扩展它

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

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

import { Observable } from 'rxjs';
let temp123 = new Observable<String>();
这就是它的工作方式:

当您编写
import{Observable}时,从'rxjs'导入{Observable}
typescript在
node\u modules
中找到
rxjs
文件夹,其中包含
package.json
,其中

 "typings": "Rx.d.ts"
这是
rxjs
的类型声明文件,该文件包含

  export { Observable } from './Observable';
它使typescript在同一文件夹中找到另一个类型声明文件,
Observable.d.ts
,该文件夹已导出
Observable
类的声明

这足以让您的代码编译时不出错

如果您的代码实际上没有尝试使用
Observable
作为值,那么它会起作用,因为typescript会这样做-如果
Observable
仅用于类型检查,就像在第二个示例中一样,在生成的javascrpt中不会有
require('rxjs')
调用

现在,SystemJS

SystemJS没有任何用于查找模块的默认位置-它甚至无法识别具有
main
属性的节点模块关于
package.json
文件的约定

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

    SystemJS.config({
        paths: {'npm:': 'node_modules/'},
        map: {'rxjs': 'npm:rxjs'},
        packages: {
            rxjs: {
            }
        }
    });
因此,此行导入的模块
rxjs/Observable

import { Observable } from 'rxjs/Observable';
映射到

node_modules/rxjs/Observable.js
因为
rxjs
前缀匹配
map
条目,该条目与
路径一起
将其映射到
node\u模块/rxjs

可观察的
零件按原样通过

添加
.js
扩展名是因为
rxjs
与systemjs配置中的
rxjs
包匹配,对于属于包的任何模块,systemjs会自动添加
.js
扩展名,除非
defaultExtension
在该包配置中设置为其他内容

它可以工作,因为存在文件
node\u modules/rxjs/Observable.js

这种导入也适用于typescript,因为
node\u modules/rxjs/Observable.d.ts
也存在

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

import { Observable } from 'rxjs';
因为它被映射到
node\u modules/rxjs
url,并且那里没有实际的文件

您可以使用SystemJS包配置中的
main
属性来修复它:

        packages: {
            rxjs: {
                main: 'Rx.js'
            }
        }
现在它被映射到
node\u modules/rxjs/Rx.js
,并且该文件实际上存在并导出名为
Observable
的内容,因此它应该可以工作


通过SystemJS 0.19.43、rxjs 5.0.3、typescript 2.1.5进行检查。

关于我的SystemJS.config,您是正确的。而且你的修复工作。您认为将“main”添加到systemjs.package.config是比更改导入语句更好还是更差的解决方案?令人惊讶的详细答案,顺便说一句。我认为添加
main
有更好的机会继续工作,当(如果)你将使用systemjs builder打包你的应用程序时,但我自己没有用rxjs做过,所以我可能错了。如果rxjs的作者对此有任何意见的话,了解他们的意见将是很有趣的。@artem。我一直在想从“rxjs”导入
和从“rxjs/Observable”导入
的区别有一段时间了。谢谢你的解释。这是一个令人惊讶的描述。我觉得您已经在一条评论中解释了整个js模块导入过程。