如何使用 systemjs 在最小的 Angular 2 应用程序中加载 RxJS?
Posted
技术标签:
【中文标题】如何使用 systemjs 在最小的 Angular 2 应用程序中加载 RxJS?【英文标题】:How to load RxJS in a minimal Angular 2 app using systemjs? 【发布时间】:2016-01-27 13:34:08 【问题描述】:我无法使用 RxJS 获得最小的 Angular 2 应用程序。我正在使用 Typescript (tsc 1.6.2) 和 systemjs 进行模块加载。如何让 systemjs 正确加载 Rx 模块?我已经没有什么想法可以尝试了,如果我能指出我做错了什么,我将不胜感激。模块加载对我来说有点神奇。非常沮丧。
index.html:
<!DOCTYPE html>
<html>
<head>
<title>Title</title>
<script src="../node_modules/es6-shim/es6-shim.js"></script>
<script src="../node_modules/systemjs/dist/system.src.js"></script>
<script src="../node_modules/rx/dist/rx.lite.js"></script>
<script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
</head>
<body>
<app>App loading...</app>
<script>
System.config(
packages: 'app': defaultExtension: 'js'
);
System.import('app/app');
</script>
</body>
</html>
app.ts:
/// <reference path="../../node_modules/rx/ts/rx.all.d.ts" />
import bootstrap, Component, View from 'angular2/angular2';
import * as Rx from 'rx';
@Component(
selector: 'app'
)
@View(
template: `Rx Test`
)
export class App
subject: Rx.Subject<any> = new Rx.Subject<any>();
bootstrap(App);
SystemJS 尝试加载一个不存在的文件:
只要我在上面的代码中注释掉 subject,一切都会运行良好,因为不会尝试加载不存在的文件(并且不会加载 rx)。 p>
【问题讨论】:
【参考方案1】:更新 angular2 beta 0
Angular2 不再将 RxJS 捆绑在 Angular2 本身中。现在您必须单独导入运算符。这是我answered here 的重要突破性变化。因此,请参考该答案,因为该答案已过时且不再适用。
2015 年 12 月 11 日更新
Alpha46 正在使用 RxJS alpha 0.0.7(即将成为 0.0.8)。由于这个 ng2 alpha 版本您不再需要下面的解决方案,您现在可以直接从 angular2/angular
导入 Observable
、Subject
等,因此可以丢弃原始答案
import Observable, Subject from 'angular2/angular2';
======================================
Angular2 不再使用旧的RxJS,他们移到了新的RxJS 5(又名 RxJS Next),所以它会与 Http 和 EventEmitter 发生冲突。
所以首先删除 rx.lite.js 的导入和脚本。
相反,您必须这样做(您的配置中不需要脚本或映射)
编辑
这一行是为了让它在 plnkr 中工作,但在我的项目中我只需要添加一些其他的东西
Plnkr 版本
import Subject from '@reactivex/rxjs/dist/cjs/Subject';
离线版
import * as Subject from '@reactivex/rxjs/dist/cjs/Subject';
离线版注意事项
如果您在本地项目中尝试第一种 plnkr 方法,您可能会收到此消息错误
TypeError: Subject_1.default is not a function
因此,对于您的本地(离线)版本,您应该使用第二种方法(使用星号)。
注意
Subject
中没有括号,this conversation 中对此进行了解释(我遇到了同样的问题,哈哈)
这是plnkr not failing。
我希望它有所帮助。如果我错过了什么,请告诉我;)
【讨论】:
埃里克,感谢您抽出宝贵时间回复!这为我解决了部分谜团。很抱歉花了这么长时间才回复你,我今天大部分时间都在试图让同一个项目离线工作(我必须说没有任何真正的成功)。我正在使用 VSC 和 Typescript 1.6.2,与您的示例中使用的转译器相同。在“在线”版本中从 app.ts 生成的代码有一个稍微不同的标头,这似乎产生了很大的不同(它调用System.register(...)
)。你有没有成功地用 VSC/tsc 在本地编译和运行它?
您是否遇到任何错误?事实上,在我的离线版本(我自己的项目)中,我有import * as Subject from '...'
(与我的答案有点不同。你还有别的吗?你的在线版本和离线版本有多大不同?
所以您在运行时遇到错误?还是默默地失败了?您是否在使用诸如 JSPM、Webpack 之类的工具?你可以创建一个 repo 以便我可以克隆它并查看它吗?
没有错误,转译没问题,智能感知工作(为此,我在 npm_modules 中添加了@reactivex alpha 4,与角度使用相同)。它在运行时 (TypeError: Subject_1.default is not a function
) 失败,因为它似乎没有加载 rx 模块/类型。我将 config.js 更改为加载“app.js”和默认分机“js”,并删除了 index.html 中对 typescript.js 的引用。这让我发疯了。
好吧,这很有趣。编译器会抱怨,但生成的输出与在线版本中生成的输出相同 - 并且它在运行时工作。因此,除了 tsc 输出 (src/app.ts(11,14): error TS2304: Cannot find name 'Subject'. src/app.ts(11,29): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
) 之外一切正常。非常感谢你的帮助。下一杯啤酒在我身上:)。【参考方案2】:
对于 angular2 alpha52 使用 rxjs 5alpha.14
<script>
System.config(
map: rxjs: 'node_modules/rxjs' ,
packages:
rxjs: defaultExtension: 'js' ,
'app': defaultExtension: 'js'
);
System.import('app/app');
</script>
但您必须像此示例一样单独导入每个运算符
import Subject from 'rxjs/Subject';
import Observable from 'rxjs/Observable';
require('rxjs/add/operator/map');
require('rxjs/add/operator/scan');
require('rxjs/add/operator/mergemap'); //for flatmap
require('rxjs/add/operator/share');
require('rxjs/add/operator/combinelatest-static'); //for combinelatest
【讨论】:
【参考方案3】:在 Angular 4 发布后发布此答案。尝试从 Rxjs 加载最低限度,因为即使使用 AOT 的 Angular prod build 也会达到 300kb
希望对你有帮助。
import Injectable from '@angular/core';
import Http from "@angular/http";
import Observable from "rxjs/Observable";
import 'rxjs/add/operator/map';// load this in main.ts
import AllUserData from "../../../shared/to/all-user-data";
@Injectable()
export class ThreadsService
constructor(private _http: Http)
loadAllUserData(): Observable<AllUserData>
return this._http.get('/api/threads')
.map(res => res.json());
【讨论】:
以上是关于如何使用 systemjs 在最小的 Angular 2 应用程序中加载 RxJS?的主要内容,如果未能解决你的问题,请参考以下文章
如何正确地将 Polyfills 添加到 SystemJS Angular 4 应用程序
我如何实际部署 Angular 2 + Typescript + systemjs 应用程序?
“systemjs-builder”:如何将 js 文件中的所有依赖项构建到一个 bundle.js 文件中