使用 SystemJs 加载 rxjs 包的问题
Issue loading rxjs bundle with SystemJs
版本
npm: 3.10.9
systemjs: 0.19.41
typescript: 1.8.10
rxjs: 5.0.3
背景
我有一个项目(用 typescript 编写),我正在尝试将 rxjs
添加到其中,但是在通过 systemjs
.[=38 加载捆绑文件时遇到了问题=]
SystemJs 配置
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
}
}
});
问题
使用上面的配置,我得到以下错误。
Error: (SystemJS) undefined is not a constructor (evaluating '__extends(UnsubscriptionError, _super)')
这是由于 systemjs 错误地默认为 amd
格式,并且 Rx.js
的第 245 行的 exporter
函数永远不会执行。
来自 systemjs 文档:
Module format detection
When the module format is not set, automatic regular-expression-based detection is used. This module format detection is never completely accurate, but caters well for the majority use cases.
尝试的解决方案
我认为在配置中将 rxjs
包格式显式设置为 global
可以解决此问题。
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
},
rxjs: {
format: 'global'
}
}
});
问题2
虽然这解决了第一个问题,但也造成了第二个问题。因为我尝试使用 rxjs
导入的任何地方现在都会抛出错误,因为它们是 undefined
.
import {Observable} from 'rxjs'
export class SomeClass {
...
private _isObservable(arg: any): boolean {
return arg instanceof Observable;
}
}
Uncaught TypeError: Right-hand side of 'instanceof' is not an object at SomeClass._isObservable
调试控制台中的转译代码表明,虽然 window.Rx
被正确设置为 Rx
对象,但在 SomeClass
上设置的 rxjs_1_1
对象是不是全局 Rx
对象,而是另一个将 Rx
全局设置为 属性 'Rx' 的对象。
所以 rxjs_1.Rx.Observable
有效,但 rxjs_1.Observable` 无效。
(function(System, SystemJS) {System.register(['rxjs'], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var rxjs_1;
var SomeClass;
return {
setters:[
function (rxjs_1_1) {
rxjs_1 = rxjs_1_1;
}],
execute: function() {
SomeClass = (function () {
function SomeClass() {
}
...
SomeClass.prototype._isObservable = function (arg) {
return arg instanceof rxjs_1.Observable;
};
return SomeClass;
}());
exports_1("SomeClass", SomeClass);
}
}
});
问题
知道我如何让它传递 Rx
对象吗?
通过在 system.config
中添加 'Rx'
作为 meta.rxjs.exports
值,它允许您 select 导入 Rx
object ,而不是它的 parent。如有必要,您可以使用圆点表示法 select 甚至更深 object。
不是您想要的,只是举个例子,exports: 'Rx.Observable'
会在我的原始问题转译代码中将 属性 rxjs_1_1
设置为 Observable
。
所以完整的 system.config
将是:
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
}
},
meta: {
rxjs: {
format: 'global',
exports: 'Rx'
}
}
});
版本
npm: 3.10.9
systemjs: 0.19.41
typescript: 1.8.10
rxjs: 5.0.3
背景
我有一个项目(用 typescript 编写),我正在尝试将 rxjs
添加到其中,但是在通过 systemjs
.[=38 加载捆绑文件时遇到了问题=]
SystemJs 配置
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
}
}
});
问题
使用上面的配置,我得到以下错误。
Error: (SystemJS) undefined is not a constructor (evaluating '__extends(UnsubscriptionError, _super)')
这是由于 systemjs 错误地默认为 amd
格式,并且 Rx.js
的第 245 行的 exporter
函数永远不会执行。
来自 systemjs 文档:
Module format detection
When the module format is not set, automatic regular-expression-based detection is used. This module format detection is never completely accurate, but caters well for the majority use cases.
尝试的解决方案
我认为在配置中将 rxjs
包格式显式设置为 global
可以解决此问题。
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
},
rxjs: {
format: 'global'
}
}
});
问题2
虽然这解决了第一个问题,但也造成了第二个问题。因为我尝试使用 rxjs
导入的任何地方现在都会抛出错误,因为它们是 undefined
.
import {Observable} from 'rxjs'
export class SomeClass {
...
private _isObservable(arg: any): boolean {
return arg instanceof Observable;
}
}
Uncaught TypeError: Right-hand side of 'instanceof' is not an object at SomeClass._isObservable
调试控制台中的转译代码表明,虽然 window.Rx
被正确设置为 Rx
对象,但在 SomeClass
上设置的 rxjs_1_1
对象是不是全局 Rx
对象,而是另一个将 Rx
全局设置为 属性 'Rx' 的对象。
所以 rxjs_1.Rx.Observable
有效,但 rxjs_1.Observable` 无效。
(function(System, SystemJS) {System.register(['rxjs'], function(exports_1, context_1) {
"use strict";
var __moduleName = context_1 && context_1.id;
var rxjs_1;
var SomeClass;
return {
setters:[
function (rxjs_1_1) {
rxjs_1 = rxjs_1_1;
}],
execute: function() {
SomeClass = (function () {
function SomeClass() {
}
...
SomeClass.prototype._isObservable = function (arg) {
return arg instanceof rxjs_1.Observable;
};
return SomeClass;
}());
exports_1("SomeClass", SomeClass);
}
}
});
问题
知道我如何让它传递 Rx
对象吗?
通过在 system.config
中添加 'Rx'
作为 meta.rxjs.exports
值,它允许您 select 导入 Rx
object ,而不是它的 parent。如有必要,您可以使用圆点表示法 select 甚至更深 object。
不是您想要的,只是举个例子,exports: 'Rx.Observable'
会在我的原始问题转译代码中将 属性 rxjs_1_1
设置为 Observable
。
所以完整的 system.config
将是:
System.config({
transpiler: 'typescript',
paths: {
'src:*': '/src/*',
'npm:*': '/node_modules/*'
},
map: {
'lib': 'src:lib',
'rxjs': 'npm:rxjs/bundles/Rx.js',
'typescript': 'npm:typescript/lib/typescript.js',
'systemjs': 'npm:systemjs/dist/system.src.js'
},
packages: {
lib: {
defaultExtension: 'js'
}
},
meta: {
rxjs: {
format: 'global',
exports: 'Rx'
}
}
});