为什么以下TypeScript代码编译,但systemjs无法在运行时正确加载依赖项?
import { Observable } from 'rxjs'; let temp123 = new Observable();
但是,这有效:
import { Observable } from 'rxjs/Observable'; let temp123 = new Observable();
具体来说,第一个代码会生成一个包含以下代码的.js文件:
var Observable_1 = require('rxjs'); var temp123 = new Observable_1.Observable();
但第二个代码生成这个:
var Observable_1 = require('rxjs/Observable'); var temp123 = new Observable_1.Observable();
行require('rxjs')失败并出现404错误,因为那里没有文件.为什么typescript编译器能够解决这个问题,但是systemjs无法在运行时加载它?
另外值得注意的是:只有在使用Observable执行某些操作时才会出现此问题.例如,以下代码有效:
import { Observable } from 'rxjs'; let temp123: Observable= null; let 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';
typescript rxjs
时node_modules
,package.json
在其中找到了包含的文件夹
"typings": "Rx.d.ts"
那个类型声明文件rxjs
,该文件包含
export { Observable } from './Observable';
这使得typescript在同一个文件夹中找到另一个类型声明文件Observable.d.ts
,它已经为Observable
类导出了声明.
这足以让您的代码无错误地编译.
如果您的代码实际上没有尝试Observable
用作值,它将起作用,因为typescript会使用未使用的引用省略 - 如果Observable
仅用于类型检查,如在第二个示例中,require('rxjs')
生成的javascrpt 中将不会调用.
现在,SystemJS.
SystemJS没有任何默认位置来查找模块 - 它甚至不识别有关package.json
带有main
属性的文件的node_modules约定.
因此,您的示例中的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
条目,并与其一起paths
映射node_modules/rxjs
Observable
部分按原样通过
.js
添加扩展名是因为rxjs
与rxjs
systemjs config中的包匹配,并且对于属于包的任何模块,SystemJS会.js
自动添加扩展名,除非defaultExtension
在该包配置中设置为其他内容.
它有效,因为文件node_modules/rxjs/Observable.js
存在.
而且导入也适用于打字稿,因为也node_modules/rxjs/Observable.d.ts
存在.
最后,这在运行时不起作用
import { Observable } from 'rxjs';
因为它映射到node_modules/rxjs
url,并且那里没有实际文件.
您可以通过使用main
SystemJS包配置中的属性来修复它:
packages: { rxjs: { main: 'Rx.js' } }
现在它已映射到node_modules/rxjs/Rx.js
,并且该文件实际存在并导出了一些名为的内容Observable
,因此它应该可以正常工作.
使用SystemJS 0.19.43,rxjs 5.0.3,typescript 2.1.5进行检查.