Angular app的条件编译

时间:2017-05-10 22:02:22

标签: angular typescript webpack

我试图使用Webpack模拟Angular Tour of Heroes,让它在浏览器和Electron中都能正常工作。我想条件创建HeroService类,并为浏览器提供直接的REST请求,并使用IPC让主进程在使用Electron时执行此操作。我对Typescript仍然很陌生,所以我不确定它是否可能发生。 TARGET是一个配置文件变量,用于确定webpack目标应该是web还是electron-renderer。我无法让awesome-typescript-loader仅有条件地执行let ipc = require('electron').ipcRenderer。当我将目标设置为electron-renderer并且可以在Electron中使用它时,它可以工作,但当然包含节点集成,因此当我尝试在浏览器中运行时,我会使用require。我已经尝试过将服务作为一个类和一个对象,但没有运气。这是一个例子。

import {Injectable} from '@angular/core';
import {Headers, Http} from '@angular/http';
import {Hero} from './hero';
import axios from 'axios';
import {DB_HOST, DB_PORT, API_URL, TARGET} from '../../config/';
const heroesUrl = `http://${DB_HOST}:${DB_PORT}/${API_URL}`;

type HeroServiceType = {
  getHeroes: () => Promise<Hero[]>,
  getHero: (id: number) => Promise<Hero>,
  delete: (id: number) => Promise<void>,
  create: (name: string) => Promise<Hero>,
  update: (hero: Hero) => Promise<Hero>
}

let ipc: typeof ipcRenderer;

let HeroService: HeroServiceType;

if (TARGET === 'web') {
  HeroService = {
    getHeroes: () => {
      return axios.get(heroesUrl)
      .then(response => response.data)
      .catch(err => handleError(err));
    },

    getHero: (id) => {
      return axios.get(`${heroesUrl}/${id}`)
      .then(response => response.data[0])
      .catch(err => handleError(err));
    },

    delete: (id) => {
      return axios.delete(`${heroesUrl}/${id}`)
      .then(() => null)
      .catch(err => handleError(err));
    },

    create: (name) => {
      return axios.post(
        heroesUrl,
        JSON.stringify({name}),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(response => response.data)
      .catch(err => handleError(err));
    },

    update: (hero) => {
      return axios.put(
        `${heroesUrl}/${hero.id}`,
        JSON.stringify(hero),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(() => hero)
      .catch(err => handleError(err));
    }
  };
}

else {
  let ipc = require('electron').ipcRenderer;

  const handleIPC = function(method: string, query: object): Promise<any> {
    ipc.send(method, query);
    return new Promise((resolve) => {
      ipc.once(method, (event, args) => {
        if (args.err) handleError(args.err);
        else if (args.data) resolve(args.data);
        else resolve();
      });
    });
  }

  HeroService = {
    getHeroes: function() {
      return handleIPC('getAll', {});
    },

    getHero: function(id) {
      return handleIPC('get', {id});
    },

    delete: function(id) {
      return handleIPC('delete', {id});
    },

    create: function(name) {
      return handleIPC('create', {name});
    },

    update: function(hero) {
      return handleIPC('update', {hero});
    }
  };
}

function handleError(error: any): Promise<any> {
  console.error('An error occurred', error);
  return Promise.reject(error.message || error);
}

export {HeroService, HeroServiceType};

我尝试过几件事。当前示例基于this post。任何有关替代方案的帮助或建议都非常感谢

这里是一个类

import {Injectable} from '@angular/core';
import {Hero} from './hero';
import {TARGET} from '../../config';
import axios from 'axios';
import {ipcRenderer} from 'electron';

@Injectable()
export class HeroService {
  private heroesUrl = 'http://localhost:8081/api/heroes';

  getHeroes(): Promise<Hero[]> {
    if (TARGET === 'web') {
      return axios.get(this.heroesUrl)
      .then(response => response.data as Hero[])
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('getAll', {});
    }
  }

  getHero(id: number): Promise<Hero> {
    const url = `${this.heroesUrl}/${id}`;
    if (TARGET === 'web') {
      return axios.get(url)
      .then(response => response.data as Hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('get', {id});
    }
  }

  delete(id: number): Promise<void> {
    const url = `${this.heroesUrl}/${id}`;
    if (TARGET === 'web') {
      return axios.delete(url)
      .then(() => null)
      .catch(this.handleError);
    }
    else {
      this.handleIPC('delete', {id});
    }
  }

  create(name: string): Promise<any> {
    if (TARGET === 'web') {
      return axios.post(
        this.heroesUrl,
        JSON.stringify({name}),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(response => response.data as Hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('create', {name});
    }
  }

  update(hero: Hero): Promise<any> {
    const url = `${this.heroesUrl}/${hero.id}`;
    if (TARGET === 'web') {
      return axios.put(
        url,
        JSON.stringify(hero),
        {
          headers: {'Content-Type': 'application/json'}
        }
      )
      .then(() => hero)
      .catch(this.handleError);
    }
    else {
      return this.handleIPC('update', {hero});
    }
  }

  private handleIPC(method: string, query: object) {
    ipcRenderer.send(method, query);
    return new Promise((resolve) => {
      ipcRenderer.once(method, (event, args) => {
        if (args.err) this.handleError(args.err);
        else if (args.data) resolve(args.data);
        else resolve();
      });
    });
  }

  private handleError(error: any): Promise<any> {
    console.log('An error occured', error);
    return Promise.reject(error.message || error);
  }
}

0 个答案:

没有答案