为什么以下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
答案 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进行检查。