在Angular2应用程序中使用GeoFire [英] Using GeoFire in an Angular2 App

查看:204
本文介绍了在Angular2应用程序中使用GeoFire的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的Angular2(RC5)应用程序中设置GeoFire。我已经用npm安装了geofire和firebase,并且配置了systemjs来导入它。这里是我的package.json:

$
$名称$ MyProject
version :0.1.0,
scripts:{
start:tsc&&&& ,
lite:lite-server,
postinstall:typings install,
tsc:tsc,
tsc:w :tsc -w,
typings:typings
},
license:ISC,
dependencies:{
@ angular / common:^ 2.0.0-rc.5,
@ angular / compiler:^ 2.0.0-rc.5,
@ angular / core :^ 2.0.0-rc.5,
@ angular / forms:0.3.0,
@ angular / http:2.0.0-rc.5,
@ angular / platform-b​​rowser:^ 2.0.0-rc.5,
@ angular / platform-b​​rowser-dynamic:^ 2.0.0-rc.5,
@ angular / router:3.0.0-rc.1,
@ angular / router-deprecated:2.0.0-rc.2,
@内存中的web-api:0.0.15,
bootstrap:^ 3.3.6 ,
c ore-js:^ 2.4.0,
firebase:^ 3.3.0,
geofire:^ 4.1.1,
reflect-metadata :^ 0.1.3,
rxjs:5.0.0-beta.6,
systemjs:0.19.27,
zone.js :^ 0.6.12
},
devDependencies:{
concurrently:^ 2.0.0,
lite-server:^ 2.2 .0,
typescript:^ 1.8.10,
typings:^ 1.0.4
}
}


和我的systemjs配置文件

  var map = {
'app':'app',// dist',
'@angular':'node_modules / @ angular',
'angular2-in-memory -web-api':'node_modules / angular2-in-memory-web-api',
'rxjs':'node_modules / rxjs',
'firebase':'node_modules / firebase',
'geofire':'node_modules / geofire',
};
// package告诉系统加载器如何在没有文件名和/或没有扩展时加载
var packages = {
'app':{main:'main.js',defaultExtension:' js'},
'rxjs':{defaultExtension:'js'},
'angular2-in-memory-web-api':{main:'index.js',defaultExtension:'js' },
'firebase':{main:'firebase.js',defaultExtension:'js'},
'geofire':{main:'dist / geofire.js',defaultExtension:'js' },
};

最后,我尝试在我的app.component.ts文件中导入geofire,如下所示:

 导入*作为GeoFire从geofire; 

但是在运行npm start开始运行并启动服务器时,出现以下错误:

 ➜MyProject npm start 

> MyProject@0.1.0 start / Users / max / Development / myproject
> tsc&&同时npm run tsc:wnpm run lite

app / app.component.ts(3,26):错误TS2307:无法找到模块geofire。

npm ERR!达尔文15.5.0
npm ERR! argv/usr/local/Cellar/node/5.10.1/bin/node/ usr / local / bin / npmstart
npm ERR!节点v5.10.1
npm ERR! npm v3.8.3
npm ERR!代码ELIFECYCLE
npm ERR! MyProject@0.1.0 start:`tsc&&同时npm run tsc:wnpm run lite`
npm ERR!退出状态2
npm ERR!
npm ERR!在MyProject@0.1.0启动脚本tsc&&同时npm run tsc:wnpm run lite。
npm ERR!确保你已经安装了最新版本的node.js和npm。
npm ERR!如果这样做,这很可能是MyProject包
npm ERR!而不是npm本身。
npm ERR!告诉作者,你的系统失败了:
npm ERR! tsc&&同时npm run tsc:wnpm run lite
npm ERR!您可以通过以下方式获得有关如何为此项目打开问题的信息:
npm ERR! npm错误MyProject
npm ERR!或者,如果不可用,您可以通过以下方式获取他们的信息:
npm ERR! npm所有者ls MyProject
npm ERR!上面可能还有额外的日志输出。

npm ERR!请包括以下任何支持请求的文件:
npm ERR! /Users/max/Development/MyProject/npm-debug.log

这是我的tsconfig:

  {
compilerOptions:{
target:es5,
module :commonjs,
moduleResolution:node,
sourceMap:true,
emitDecoratorMetadata:true,
experimentalDecorators:true,
removeComments:false,
noImplicitAny:false
}
}

剩下的项目文件是基于这里找到的angular2 quickstart:

https://angular.io/guide/quickstart



有人知道我怎样才能得到tsc找到模块,并成功地transpile?



谢谢。这个快速入门教程缺少一个重要的观点:SystemJS和TypeScript是两个独立的工具,每个工具都有自己的配置。

在systemjs config中添加geofire对打印机模块的分辨率没有影响。看到这个导入

  import *作为GeoFire从geofire; 



tsc尝试在通常会发现javascript模块类型的地方寻找geofire.ts,并给出一个错误,因为它不在那里。

有三种不同的方法来解决这个问题。在任何情况下,systemjs.config.js中的 geofire 程序包配置必须声明其格式为 global ,如下所示:

 'geofire':{
main:' dist / geofire.js',
defaultExtension:'js',
meta:{'dist / geofire.js':{format:'global'}}
},

第一个解决方案是使用环境模块为geofire自己创建最简单的类型声明。
$ b

在app文件夹中创建 geofire.d.ts 文件:

<$ p $声明namespace geofire {
函数GeoFire(firebaseRef:any):void;
}

declare module'geofire'{
export = geofire;





这对于导入语句来说是足够的了,对于这个调用来说,

  var geoFire = new GeoFire(firebaseRef); 

打字稿2.0



对于typescript 2.0,上面的代码不起作用。你必须使用typecript特定的 import = 语法

  import GeoFire =要求( 'geofire'); 

并更改 geofire.d.ts 到:


$ b $ pre $ declare module'geofire'{
function GeoFire(firebaseRef:any):void;
export = GeoFire;
}

解决这个问题的另一种方法是使用插件为SystemJS使用TypeScript API调用打字稿和挂钩到其模块分辨率,以便它考虑SystemJS配置。使用该插件,该导入将在运行时在浏览器中运行,但是从命令行调用tsc仍然会导致相同的错误。第三种方法是使用SystemJS API导入geofire,而不是app.component.ts中的import语句:

 从'@ angular / core'导入{Component}; 

declare var SystemJS:any;
var GeoFirePromise = SystemJS.import('geofire');

@Component({
selector:'my-app',
template:'< h1> My First Angular 2 App< / h1>'
} )
$ b $ export class AppComponent {

constructor(){//或者任何需要使用geofire的地方

GeoFirePromise.then(function(GeoFire:任何){
console.log(typeof GeoFire);
});





注意 SystemJS.import 返回一个承诺,将不得不加载geofire.js,所以你想要使用它的任何地方你必须做的

<$ p $ GeoFirePromise.then(GeoFire:any){

如果这个不方便,你可以声明全局GeoFire变量
$ b $ pre $ declare var GeoFire:any;

并使用脚本标记在您的HTML中加载geofire.js,如这篇文章在离子论坛上然后,你不需要添加geofire到systemjs.config.js。 p>

I'm trying to set up GeoFire in my Angular2 (RC5) app. I've installed geofire and firebase with npm and configured systemjs to import it. Here's my package.json:

{
  "name": "MyProject",
  "version": "0.1.0",
  "scripts": {
    "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\" ",
    "lite": "lite-server",
    "postinstall": "typings install",
    "tsc": "tsc",
    "tsc:w": "tsc -w",
    "typings": "typings"
  },
  "license": "ISC",
  "dependencies": {
    "@angular/common": "^2.0.0-rc.5",
    "@angular/compiler": "^2.0.0-rc.5",
    "@angular/core": "^2.0.0-rc.5",
    "@angular/forms": "0.3.0",
    "@angular/http": "2.0.0-rc.5",
    "@angular/platform-browser": "^2.0.0-rc.5",
    "@angular/platform-browser-dynamic": "^2.0.0-rc.5",
    "@angular/router": "3.0.0-rc.1",
    "@angular/router-deprecated": "2.0.0-rc.2",
    "@angular/upgrade": "2.0.0-rc.5",
    "angular2-in-memory-web-api": "0.0.15",
    "bootstrap": "^3.3.6",
    "core-js": "^2.4.0",
    "firebase": "^3.3.0",
    "geofire": "^4.1.1",
    "reflect-metadata": "^0.1.3",
    "rxjs": "5.0.0-beta.6",
    "systemjs": "0.19.27",
    "zone.js": "^0.6.12"
  },
  "devDependencies": {
    "concurrently": "^2.0.0",
    "lite-server": "^2.2.0",
    "typescript": "^1.8.10",
    "typings": "^1.0.4"
  }
}

and my systemjs config file:

  var map = {
    'app':                        'app', // 'dist',
    '@angular':                   'node_modules/@angular',
    'angular2-in-memory-web-api': 'node_modules/angular2-in-memory-web-api',
    'rxjs':                       'node_modules/rxjs',
    'firebase':                   'node_modules/firebase',
    'geofire':                    'node_modules/geofire',
  };
  // packages tells the System loader how to load when no filename and/or no extension
  var packages = {
    'app':                        { main: 'main.js',  defaultExtension: 'js' },
    'rxjs':                       { defaultExtension: 'js' },
    'angular2-in-memory-web-api': { main: 'index.js', defaultExtension: 'js' },
    'firebase':                   { main: 'firebase.js', defaultExtension: 'js' },
    'geofire':                    { main: 'dist/geofire.js', defaultExtension: 'js' },
  };

Finally I try to import geofire in my app.component.ts file like so:

import * as GeoFire from "geofire";

But on running npm start to transpile and launch the server, get the following error:

➜  MyProject npm start

> MyProject@0.1.0 start /Users/max/Development/myproject
> tsc && concurrently "npm run tsc:w" "npm run lite"

app/app.component.ts(3,26): error TS2307: Cannot find module 'geofire'.

npm ERR! Darwin 15.5.0
npm ERR! argv "/usr/local/Cellar/node/5.10.1/bin/node" "/usr/local/bin/npm" "start"
npm ERR! node v5.10.1
npm ERR! npm  v3.8.3
npm ERR! code ELIFECYCLE
npm ERR! MyProject@0.1.0 start: `tsc && concurrently "npm run tsc:w" "npm run lite" `
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the MyProject@0.1.0 start script 'tsc && concurrently "npm run tsc:w" "npm run lite" '.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the MyProject package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     tsc && concurrently "npm run tsc:w" "npm run lite"
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs MyProject
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls MyProject
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/max/Development/MyProject/npm-debug.log

Here's my tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

The rest of the project files are based on the angular2 quickstart found here:

https://angular.io/guide/quickstart

Does anybody have any idea how I can get tsc to find the module and successfully transpile?

Thanks. Max.

解决方案

That quickstart tutorial is missing one important point: SystemJS and TypeScript are two separate tools, each with its own configuration.

Adding geofire to systemjs config has no effect on typescript module resolution. Upon seeing this import

import * as GeoFire from "geofire";

tsc tries to find geofire.ts in usual places where typings for javascript modules are normally found, and gives an error because it's not there.

There are three different ways to solve this problem.

In any case, geofire package configuration in systemjs.config.js must declare its format as global, like this:

'geofire': {
    main: 'dist/geofire.js', 
    defaultExtension: 'js', 
    meta: {'dist/geofire.js': {format: 'global'}} 
 },

The first solution is to create the simplest possible type declaration for geofire yourself, using ambient modules.

Create geofire.d.ts file in the app folder:

declare namespace geofire {
    function GeoFire(firebaseRef: any): void;
}

declare module 'geofire' {
    export = geofire;
}

This is sufficient for import statement to compile, and for this call to typecheck:

   var geoFire = new GeoFire(firebaseRef);

NOTE for typescript 2.0

For typescript 2.0 the code above does not work. You have to use typescript-specific import = syntax

import GeoFire = require('geofire');

and change definition in geofire.d.ts to:

declare module 'geofire' {
    function GeoFire(firebaseRef: any): void;
    export = GeoFire;
}

Yet another possible way to solve this is to use a plugin for SystemJS that uses TypeScript API to invoke typescript and hook into its module resolution, so that it takes into account SystemJS configuration. With that plugin, that import will work at runtime in the browser, but invoking tsc from the command line would still give the same error.

The third way is to import geofire using SystemJS API, not the import statement in app.component.ts:

import { Component } from '@angular/core';

declare var SystemJS : any;
var GeoFirePromise = SystemJS.import('geofire');

@Component({
  selector: 'my-app',
  template: '<h1>My First Angular 2 App</h1>'
})

export class AppComponent {

    constructor() {  // or wherever you need to use geofire

        GeoFirePromise.then(function(GeoFire: any) {
            console.log(typeof GeoFire);
        });
    }

}

Note that SystemJS.import returns a promise that will have to load geofire.js, so anywhere you want to use it you have to do

    GeoFirePromise.then(function(GeoFire: any) {

If this is inconvenient, you can just declare global GeoFire variable

declare var GeoFire: any;

and load geofire.js using script tag in your HTML, as described in this post on ionic forum. Then, you would not event need to add geofire to systemjs.config.js.

这篇关于在Angular2应用程序中使用GeoFire的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆